+static void glyph_transform(gfxglyph_t*g, mymatrix_t*mm)
+{
+ gfxmatrix_t m;
+ m.m00 = mm->m00;
+ m.m01 = mm->m01;
+ m.m10 = mm->m10;
+ m.m11 = mm->m11;
+ m.tx = 0;
+ m.ty = 0;
+ if(m.m00>0)
+ g->advance *= m.m00;
+ g->line = gfxline_clone(g->line);
+ gfxline_transform(g->line, &m);
+}
+
+void fontgroup_add_to_bitmap(fontgroup_t*g, transformedfont_t*f)
+{
+ int t;
+ int max = 0;
+ for(t=0;t<f->orig->num_glyphs;t++) {
+ if(f->orig->glyphs[t].unicode < 0xe000 && f->orig->glyphs[t].unicode > max) {
+ max = f->orig->glyphs[t].unicode;
+ }
+ }
+ int max64 = (max+63) >> 6;
+ if(max64 > g->bitmap_len) {
+ g->bitmap = rfx_realloc(g->bitmap, max64*sizeof(U64));
+ memset(g->bitmap+g->bitmap_len*8, 0, (max64-g->bitmap_len)*8);
+ g->bitmap_len = max64;
+ }
+ for(t=0;t<f->orig->num_glyphs;t++) {
+ int u = f->orig->glyphs[t].unicode;
+ if(u < 0xe000 && f->used[t]) {
+ g->bitmap[u >> 6] |= (1ll<<(u&63));
+ }
+ }
+ g->bitmap[0] &= ~(1ll<<32); // map out space char
+}
+
+int fontgroup_intersect(fontgroup_t*g1, fontgroup_t*g2)
+{
+ int min = g1->bitmap_len < g2->bitmap_len? g1->bitmap_len : g2->bitmap_len;
+ int t;
+ for(t=0;t<min;t++) {
+ if(g1->bitmap[t]&g2->bitmap[t]) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+fontgroup_t* fontgroup_combine(fontgroup_t*fontgroup)
+{
+ fontgroup_t*fg = fontgroup;
+ while(fg) {
+ fontgroup_t*fg2 = fg->next;
+ fontgroup_t*old = fg;
+ while(fg2) {
+ fontgroup_t*next = fg2->next;
+ if(!fontgroup_intersect(fg,fg2)) {
+ printf("combine %s and %s\n", fg->fonts->orig->id, fg2->fonts->orig->id);
+ transformedfont_t*last = fg->fonts;
+ while(last->group_next) {
+ last = last->group_next;
+ }
+ last->group_next = fg2->fonts;
+ fg2->fonts = 0;
+ old->next = next;
+ free(fg2->bitmap);
+ free(fg2);
+ } else {
+ old = fg2;
+ }
+ fg2 = next;
+ }
+ fg = fg->next;
+ }
+ return fontgroup;
+}
+