generated html version of ttfcorrect.cHOME

#include <stdio.h>
#include <stdint.h>
#include "u8.h"

typedef uint32_t u32;
typedef uint16_t u16;
//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

uint32_t read32(FILE *f){
	uint32_t c;
	fread(&c,4,1,f);
	c = c >> 16 | c << 16;
	c = c >> 8 & 0xFF00FF | c << 8 & 0xFF00FF00;
	return c;
}

void write32(FILE *f,uint32_t c){
	c = c >> 16 | c << 16;
	c = c >> 8 & 0xFF00FF | c << 8 & 0xFF00FF00;
	fwrite(&c,4,1,f);
}

uint16_t read16(FILE *f){
	uint16_t c;
	fread(&c,2,1,f);
	c = c >> 8 | c << 8;
	return c;
}

void write16(FILE *f, uint16_t c){
	c = c >> 8 | c << 8;
	fwrite(&c,2,1,f);
}

void write8(FILE *f, uint8_t c){
	fwrite(&c,1,1,f);
}

void goloc(FILE *f, long loc){
	fseek(f,loc,SEEK_SET);
}

void gorel(FILE *f, long x){
	fseek(f,x,SEEK_CUR);
}

u32 pad4(u32 x){
	return x/4 + (x%4?1:0);
}

int main(int argc, char **argv){
	FILE *f = fopen(argv[1],"r+");
	// fix the OS/2 table
	while(read32(f)!=*(u32*)"2/SO");
	unsigned cksum_loc = ftell(f);
	uint32_t cksum = read32(f);
	uint32_t os2_loc = read32(f);
	uint32_t os2_len = read32(f);
	printf("OS/2 is at %x\n",os2_loc);
	goloc(f,os2_loc+2);
	write16(f,9);//average width
	write16(f,500);//Medium Weight
	write16(f,5);//Medium Width
	goloc(f,os2_loc+32);//panose values
	write8(f,2);//Latin text
	write8(f,11);//normal sans serif
	write8(f,6);//medium weight
	write8(f,9);//monospaced
	write8(f,2);//no contrast
	write8(f,2);//no variation
	write8(f,0);//blahhhh
	write8(f,0);//blahhhh
	write8(f,0);//blahhhh
	write8(f,0);//blahhhh
	goloc(f,os2_loc+0x44);
	write16(f,12);//ascent
	write16(f,-4);//descent
	write16(f,0);//line gap
	write16(f,12);//winascent
	write16(f,4);//windescent
	u32 i,sum=0;
	goloc(f,os2_loc);
	for(i=0;i<pad4(os2_len);i++)sum += read32(f);
	goloc(f,cksum_loc);
	write32(f,sum);
	// fix horizontal header
	goloc(f,0);
	while(read32(f)!=*(u32*)"aehh");
	cksum_loc = ftell(f);
	cksum = read32(f);
	u32 hhea_loc = read32(f);
	printf("hhea is at %x\n",hhea_loc);
	u32 hhea_len = read32(f);
	goloc(f,hhea_loc+4);
	write16(f,12);
	write16(f,-4);
	write16(f,0);
	write16(f,18);
	write16(f,0);
	write16(f,0);
	write16(f,18);
	write16(f,1);
	write16(f,0);
	write16(f,0);
	write16(f,0);
	write16(f,0);
	write16(f,0);
	write16(f,0);
	write16(f,0);
	u16 hmetrics = read16(f);
	printf("there are %d hmtx\n",hmetrics);
	sum=0;
	goloc(f,hhea_loc);
	for(i=0;i<pad4(hhea_len);i++)sum += read32(f);
	goloc(f,cksum_loc);
	write32(f,sum);
	// fix horizontal metrics
	goloc(f,0);
	while(read32(f)!=*(u32*)"xtmh");
	cksum_loc = ftell(f);
	cksum = read32(f);
	u32 hmtx_loc = read32(f);
	printf("hmtx is at %x\n",hmtx_loc);
	u32 hmtx_len = read32(f);

	goloc(f,0);
	while(read32(f)!=*(u32*)"pamc");
        read32(f);//discard checksum, fuck that
        uint32_t cmap_loc = read32(f);
        printf("cmap is at %x\n",cmap_loc);
        fseek(f,cmap_loc,SEEK_SET);
	read32(f);//discard table header
        while(read32(f)!=0x3000A)//skip to UCS-4 table
                read32(f);//skip...
        uint32_t ucs4_loc = cmap_loc + read32(f);
        printf("ucs4 is at %x\n",ucs4_loc);
        fseek(f,ucs4_loc,SEEK_SET);
        if(read16(f)!=12)return(printf("ucs4 table not format 12"),1);
        fseek(f,ucs4_loc + 12,SEEK_SET);
	u32 i,n_ranges = read32(f);

	for(i=0;i<n_ranges;i++){
        	goloc(f,ucs4_loc + 16 + i*12);
                u32 sta,end;
                sta = read32(f);
                end = read32(f);
                u32 id = read32(f);//ignore glph id.
		while(sta <= end){
			if(id>=hmetrics)goto end;
			goloc(f,id*4+hmtx_loc);
			write16(f,9*u8chrwid(sta));
			sta++;
			id++;
		}
	}
end:

	sum = 0;
	goloc(f,hmtx_loc);
	for(i=0;i<pad4(hmtx_len);i++)sum += read32(f);
	goloc(f,cksum_loc);
	write32(f,sum);
	return 0;
}