bool Fraction::Intersects(const QPoint &point, GlyphList &list) { if(numerator->Intersects(point, list)) { list.push_back(this); return true; } else if(denominator->Intersects(point, list)) { list.push_back(this); return true; } return false; }
bool Function::Intersects(const QPoint &point, GlyphList &list) { if(brackets_->Intersects(point, list)) { list.back() = this; return true; } else if(name_->Intersects(point, list)) { list.back() = this; return true; } return false; }
void fixYOffset(GlyphList &glyphs) { // We try to find the minimum y offset here so we can substract it to make it 0 in the end. // We need to do this, since otherwise the characters will take up too much vertical space. int minYOffset = 0xFFFF; for (GlyphList::const_iterator i = glyphs.begin(), end = glyphs.end(); i != end; ++i) { if (i->pitch == 0) continue; minYOffset = std::min(minYOffset, i->yOffset); } // Adapt all glyphs for (GlyphList::iterator i = glyphs.begin(), end = glyphs.end(); i != end; ++i) { if (i->pitch == 0) continue; i->yOffset -= minYOffset; } }
void TrueTypeFont::renderASCIIGlyphs(GlyphList &glyphs, int &count) { count = 0; for (uint8 fB = 0x00; fB <= 0xDF; ++fB) { if (mapASCIItoChunk(fB) == -1) continue; ++count; Glyph data; if (renderGlyph(fB, 0, data)) glyphs.push_back(data); } }
void MakeFont::WriteToUnicode(GlyphList& glyphs, wxMemoryOutputStream& toUnicode) { WriteStreamBuffer(toUnicode, "/CIDInit /ProcSet findresource begin\n"); WriteStreamBuffer(toUnicode, "12 dict begin\n"); WriteStreamBuffer(toUnicode, "begincmap\n"); WriteStreamBuffer(toUnicode, "/CIDSystemInfo\n"); WriteStreamBuffer(toUnicode, "<< /Registry (Adobe)\n"); WriteStreamBuffer(toUnicode, "/Ordering (UCS)\n"); WriteStreamBuffer(toUnicode, "/Supplement 0\n"); WriteStreamBuffer(toUnicode, ">> def\n"); WriteStreamBuffer(toUnicode, "/CMapName /Adobe-Identity-UCS def\n"); WriteStreamBuffer(toUnicode, "/CMapType 2 def\n"); WriteStreamBuffer(toUnicode, "1 begincodespacerange\n"); WriteStreamBuffer(toUnicode, "<0000><FFFF>\n"); WriteStreamBuffer(toUnicode, "endcodespacerange\n"); int size = 0; size_t k; size_t numGlyphs = glyphs.GetCount(); for (k = 0; k < numGlyphs; ++k) { if (size == 0) { if (k != 0) { WriteStreamBuffer(toUnicode, "endbfrange\n"); } size = (numGlyphs-k > 100) ? 100 : numGlyphs - k; wxString sizeStr = wxString::Format(wxT("%d"), size); WriteStreamBuffer(toUnicode, sizeStr.ToAscii()); WriteStreamBuffer(toUnicode, " beginbfrange\n"); } size--; GlyphListEntry* entry = glyphs[k]; wxString fromTo = wxString::Format(wxT("<%04x>"), entry->m_gid); wxString uniChr = wxString::Format(wxT("<%04x>"), entry->m_uid); WriteStreamBuffer(toUnicode, fromTo.ToAscii()); WriteStreamBuffer(toUnicode, fromTo.ToAscii()); WriteStreamBuffer(toUnicode, uniChr.ToAscii()); WriteStreamBuffer(toUnicode, "\n"); } WriteStreamBuffer(toUnicode, "endbfrange\n"); WriteStreamBuffer(toUnicode, "endcmap\n"); WriteStreamBuffer(toUnicode, "CMapName currentdict /CMap defineresource pop\n"); WriteStreamBuffer(toUnicode, "end end\n"); }
void TrueTypeFont::renderKANJIGlyphs(GlyphList &glyphs, int &count) { count = 0; for (uint8 fB = 0x81; fB <= 0xEF; ++fB) { if (mapSJIStoChunk(fB, 0x40) == -1) continue; for (uint8 sB = 0x40; sB <= 0xFC; ++sB) { if (mapSJIStoChunk(fB, sB) == -1) continue; ++count; Glyph data; if (renderGlyph(fB, sB, data)) glyphs.push_back(data); } } }
void importDefineFont2( DefineFont2 *tag, const char *filename, xmlNodePtr node ) { FT_Library swfft_library; FT_Face face; int error; FT_UInt glyph_index; FT_ULong character; FT_Outline *outline; xmlChar *glyphs_xml = xmlGetProp( node, (const xmlChar *)"glyphs" ); const char *glyphs = (const char *)glyphs_xml; GlyphList *glyphList = tag->getglyphs(); List<Short>* advance = tag->getadvance(); List<Rectangle>* bounds = tag->getbounds(); // NYI: kerning Shape *shape; int glyph_n; int n, ofs; if( FT_Init_FreeType( &swfft_library ) ) { fprintf( stderr, "WARNING: could not initialize FreeType\n" ); goto fail; } error = FT_New_Face( swfft_library, filename, 0, &face ); if( error ) { fprintf( stderr, "WARNING: FreeType does not like %s\n", filename ); goto fail; } if( face->num_faces > 1 ) { fprintf( stderr, "WARNING: %s contains %i faces, but only the first is imported.\n", filename, face->num_faces ); } if( face->charmap == 0 ) { fprintf( stderr, "WARNING: %s doesn't seem to contain a unicode charmap.\n", filename ); } FT_Set_Char_Size(face, 1024<<6, 1024<<6, 75, 75); // we should only import @glyphs, lets do all for now. // count availably glyphs n = 0; if( (character = FT_Get_First_Char( face, &glyph_index )) != 0 ) n++; while( (character = FT_Get_Next_Char( face, character, &glyph_index )) != 0 ) n++; if( n>255 ) n=255; // FIXME ofs = 0; n-=ofs; fprintf( stderr, "importing %s: %i glyphs\n", filename, n ); glyphList->allocate( n ); tag->setglyphCount( n ); tag->setname( "helvetica" ); // FIXME tag->sethasLayout( 1 ); tag->setascent( face->ascender * 1024 / face->units_per_EM ); tag->setdescent( labs(face->descender)* 1024 / face->units_per_EM ); tag->setleading( face->height* 1024 / face->units_per_EM ); tag->setwideGlyphOffsets( 1 ); tag->setwideMap( 1 ); character = FT_Get_First_Char( face, &glyph_index ); for( int i=0; i<ofs; i++ ) character=FT_Get_Next_Char( face, character, &glyph_index ); for( int glyph_n=0; character && glyph_n<n; glyph_n++ ) { // glyph_index = FT_Get_Char_Index( face, character ); if( FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_BITMAP ) ) { fprintf( stderr, "WARNING: couldnt load glyph %i (%c) from %s.\n", character, character, filename ); } if( face->glyph->format != FT_GLYPH_FORMAT_OUTLINE ) { fprintf( stderr, "WARNING: %s seems to be a bitmap font.\n", filename ); goto fail; } outline = &face->glyph->outline; // fprintf(stderr,"importing glyph %i ('%c') of %s (advance %i, %i points)\n", character, character, filename, face->glyph->advance.x, outline->n_points ); { Short *adv = new Short(); adv->setvalue( (short)(face->glyph->advance.x * (1.0/64)) ); advance->append(adv); Rectangle *r = new Rectangle(); /* r->settop( -face->bbox.yMax * 1024 / face->units_per_EM ); r->setright( face->bbox.xMax - face->bbox.xMin ); r->setbottom( -face->bbox.yMin * 1024 / face->units_per_EM ); */ r->setbits( SWFMaxBitsNeeded( true, 3, r->gettop(), r->getright(), r->getbottom() ) ); bounds->append(r); glyphList->setMapN(glyph_n, character); shape = glyphList->getShapeN(glyph_n); ShapeMaker shaper( shape->getedges(), (1.0/64), -(1.0/64), 0, 0 ); // set fillBits shape->setfillBits(1); int start = 0, end; bool control, cubic; int n; for( int contour = 0; contour < outline->n_contours; contour++ ) { end = outline->contours[contour]; // fprintf(stderr," contour %i: %i-%i\n", contour, start, end ); n=0; for( int p = start; p<=end; p++ ) { control = !(outline->tags[p] & 0x01); cubic = outline->tags[p] & 0x02; /* if( character == 'h' ) fprintf( stderr, " point %i: %s%s %i %i\n", p, control?(cubic?"third-order ":"second-order "):"", control?"control":"on-curve", outline->points[p].x, outline->points[p].y); */ if( p==start ) { shaper.setup( outline->points[p-n].x, outline->points[p-n].y, 1 ); } if( !control && n > 0 ) { importGlyphPoints( &(outline->points[(p-n)+1]), n-1, shaper, cubic ); n=1; } else { n++; } } if( n ) { // special case: repeat first point FT_Vector points[n+1]; int s=(end-n)+2; for( int i=0; i<n-1; i++ ) { points[i].x = outline->points[s+i].x; points[i].y = outline->points[s+i].y; } points[n-1].x = outline->points[start].x; points[n-1].y = outline->points[start].y; importGlyphPoints( points, n-1, shaper, false ); } shaper.close(); start = end+1; } shaper.finish(); } character = FT_Get_Next_Char( face, character, &glyph_index ); } return; fail: fprintf( stderr, "WARNING: could not import %s\n", filename ); return; }
int main(int argc, char *argv[]) { if (argc < 2 || argc > 3) { printf("Usage:\n\t%s <input ttf font> [outfile]\n", argv[0]); return -1; } const char *font = argv[1]; const char *out = 0; if (argc == 3) out = argv[2]; else out = "sjis.fnt"; if (!initSJIStoUTF32Conversion()) { error("Could not initialize conversion from SJIS to UTF-32."); return -1; } atexit(deinitSJIStoUTF32Conversion); TrueTypeFont *ttf = new TrueTypeFont(); if (!ttf->load(font)) { delete ttf; error("Could not initialize FreeType library."); return -1; } if (!ttf->setSize(16)) { delete ttf; error("Could not setup font '%s' to size 16", font); return -1; } GlyphList glyphs; int chars8x16 = 0; int chars16x16 = 0; ttf->renderASCIIGlyphs(glyphs, chars8x16); ttf->renderKANJIGlyphs(glyphs, chars16x16); if (!ttf->setSize(12)) { delete ttf; error("Could not setup font '%s' to size 12", font); return -1; } GlyphList pceGlyphs; int chars12x12 = 0; ttf->renderKANJIGlyphs(pceGlyphs, chars12x12); delete ttf; ttf = 0; fixYOffset(glyphs); fixYOffset(pceGlyphs); // Check whether we have a character which does not fit within the boundaries for (GlyphList::const_iterator i = glyphs.begin(); i != glyphs.end(); ++i) { if (i->pitch == 0) continue; if ((isASCII(i->fB) && !i->checkSize(8, 16)) || (!isASCII(i->fB) && !i->checkSize(16, 16))) { error("Could not fit glyph for %.2X %.2X top: %d bottom: %d, left: %d right: %d, xOffset: %d, yOffset: %d, width: %d, height: %d", i->fB, i->sB, i->yOffset, i->yOffset + i->height, i->xOffset, i->xOffset + i->width, i->xOffset, i->yOffset, i->width, i->height); } } // Check whether we have a character which does not fit within the boundaries for (GlyphList::const_iterator i = pceGlyphs.begin(); i != pceGlyphs.end(); ++i) { if (i->pitch == 0) continue; if (!isASCII(i->fB) && !i->checkSize(12, 12)) { error("Could not fit pce glyph for %.2X %.2X top: %d bottom: %d, left: %d right: %d, xOffset: %d, yOffset: %d, width: %d, height: %d", i->fB, i->sB, i->yOffset, i->yOffset + i->height, i->xOffset, i->xOffset + i->width, i->xOffset, i->yOffset, i->width, i->height); } } const int sjis8x16DataSize = chars8x16 * 16; uint8 *sjis8x16FontData = new uint8[sjis8x16DataSize]; if (!sjis8x16FontData) error("Out of memory"); const int sjis16x16DataSize = chars16x16 * 32; uint8 *sjis16x16FontData = new uint8[sjis16x16DataSize]; if (!sjis16x16FontData) { delete[] sjis8x16FontData; error("Out of memory"); } const int sjis12x12DataSize = chars12x12 * 24; uint8 *sjis12x12FontData = new uint8[sjis16x16DataSize]; if (!sjis12x12FontData) { delete[] sjis8x16FontData; delete[] sjis16x16FontData; error("Out of memory"); } memset(sjis8x16FontData, 0, sjis8x16DataSize); memset(sjis16x16FontData, 0, sjis16x16DataSize); memset(sjis12x12FontData, 0, sjis12x12DataSize); for (GlyphList::const_iterator i = glyphs.begin(); i != glyphs.end(); ++i) { if (isASCII(i->fB)) { int chunk = mapASCIItoChunk(i->fB); if (chunk != -1) i->convertChar8x16(sjis8x16FontData + chunk * 16); } else { int chunk = mapSJIStoChunk(i->fB, i->sB); if (chunk != -1) i->convertChar16x16(sjis16x16FontData + chunk * 32); } } for (GlyphList::const_iterator i = pceGlyphs.begin(), end = pceGlyphs.end(); i != end; ++i) { int chunk = mapSJIStoChunk(i->fB, i->sB); if (chunk != -1) i->convertChar16x16(sjis12x12FontData + chunk * 24); } Common::File sjisFont(out, "wb"); if (sjisFont.isOpen()) { // Write our magic bytes sjisFont.writeUint32BE(MKID_BE('SCVM')); sjisFont.writeUint32BE(MKID_BE('SJIS')); // Write version sjisFont.writeUint32BE(0x00000003); // Write character count sjisFont.writeUint16BE(chars16x16); sjisFont.writeUint16BE(chars8x16); sjisFont.writeUint16BE(chars12x12); sjisFont.write(sjis16x16FontData, sjis16x16DataSize); sjisFont.write(sjis8x16FontData, sjis8x16DataSize); sjisFont.write(sjis12x12FontData, sjis12x12DataSize); delete[] sjis8x16FontData; delete[] sjis16x16FontData; delete[] sjis12x12FontData; if (sjisFont.err()) error("Error while writing to font file: '%s'", out); } else { delete[] sjis8x16FontData; delete[] sjis16x16FontData; delete[] sjis12x12FontData; error("Could not open file '%s' for writing", out); } return 0; }