#ifndef __LP64__ #include #include #include #include "tmathutil.h" #include "tdebugmessage.h" #include "tfont.h" #include "tstroke.h" #include "tcurves.h" #include "tconvert.h" #include "tvectorimage.h" using namespace std; //----------------------------------------- structures //------------------------------------------------------------------- typedef struct { Float32Point origin; // The origin of the current glyph Boolean first; // Keeps track of which segment is first in a glyph Float32Point current; // The current pen position (used to filter degenerate cases) float adv; TVectorImageP m_image; std::vector m_points; } MyCurveCallbackData; typedef struct { ATSGlyphRef glyphID; // The glyphID. This is simply an index into a table in // the font. Float32Point relativeOrigin; // The origin of this glyph -- relative to the // origin of the line. } MyGlyphRecord; //----------------------------------------- //callback--------------------------------------------------------------------- OSStatus MyQuadraticLineProc(const Float32Point *pt1, const Float32Point *pt2, void *callBackDataPtr) { /* // Adjust the points according to the glyph origin float x1 = ((MyCurveCallbackData *)callBackDataPtr)->origin.x + pt1->x; float y1 = ((MyCurveCallbackData *)callBackDataPtr)->origin.y + pt1->y; float x2 = ((MyCurveCallbackData *)callBackDataPtr)->origin.x + pt2->x; float y2 = ((MyCurveCallbackData *)callBackDataPtr)->origin.y + pt2->y; */ MyCurveCallbackData *data = (MyCurveCallbackData *)callBackDataPtr; if (data->m_points.empty()) data->m_points.push_back(TThickPoint(pt1->x, pt1->y, 0)); // else // assert(isAlmostEqual(pt1 e back) TThickPoint lastPoint = TThickPoint(pt2->x, pt2->y, 0); data->m_points.push_back((data->m_points.back() + lastPoint) * 0.5); data->m_points.push_back(lastPoint); return noErr; } OSStatus MyQuadraticCurveProc(const Float32Point *pt1, const Float32Point *controlPt, const Float32Point *pt2, void *callBackDataPtr) { /* // Adjust the points according to the glyph origin float x1 = ((MyCurveCallbackData *)callBackDataPtr)->origin.x + pt1->x; float y1 = ((MyCurveCallbackData *)callBackDataPtr)->origin.y + pt1->y; float x2 = ((MyCurveCallbackData *)callBackDataPtr)->origin.x + pt2->x; float y2 = ((MyCurveCallbackData *)callBackDataPtr)->origin.y + pt2->y; float cpx = ((MyCurveCallbackData *)callBackDataPtr)->origin.x + controlPt->x; float cpy = ((MyCurveCallbackData *)callBackDataPtr)->origin.y + controlPt->y; */ MyCurveCallbackData *data = (MyCurveCallbackData *)callBackDataPtr; if (data->m_points.empty()) data->m_points.push_back(TThickPoint(pt1->x, pt1->y, 0)); // else // assert(isAlmostEqual(pt1 e back) data->m_points.push_back(TThickPoint(controlPt->x, controlPt->y, 0)); data->m_points.push_back(TThickPoint(pt2->x, pt2->y, 0)); return noErr; } OSStatus MyQuadraticNewPathProc(void *callBackDataPtr) { assert(((MyCurveCallbackData *)callBackDataPtr)->m_points.empty()); return noErr; } OSStatus MyQuadraticClosePathProc(void *callBackDataPtr) { MyCurveCallbackData *data = (MyCurveCallbackData *)callBackDataPtr; assert( data->m_points.size() >= 3 && data->m_points.size() & 1); // il numero di punti di controllo devono essere dispari e >= 3 TStroke *stroke = new TStroke(data->m_points); stroke->setSelfLoop(true); data->m_points.clear(); data->m_image->addStroke(stroke); return noErr; } //------------------------------------------------------------------------------------------------------------------ void GetGlyphIDsAndPositions(ATSUTextLayout iLayout, UniCharArrayOffset iStart, UniCharCount iLength, MyGlyphRecord **oGlyphRecordArray, ItemCount *oNumGlyphs) { // This block of code uses the new Direct Access APIs, which are only // available on Mac OS X 10.2 and later systems // ATSLayoutRecord *layoutRecords; ItemCount numRecords; Fixed *deltaYs; ItemCount numDeltaYs; unsigned int i; OSStatus status; // Get the arrays of glyph information status = ATSUDirectGetLayoutDataArrayPtrFromTextLayout( iLayout, iStart, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, (void **)&layoutRecords, &numRecords); assert(status == noErr); status = ATSUDirectGetLayoutDataArrayPtrFromTextLayout( iLayout, iStart, kATSUDirectDataBaselineDeltaFixedArray, (void **)&deltaYs, &numDeltaYs); assert(status == noErr); // Build the array of MyGlyphRecords *oGlyphRecordArray = (MyGlyphRecord *)malloc(numRecords * sizeof(MyGlyphRecord)); *oNumGlyphs = numRecords; for (i = 0; i < *oNumGlyphs; i++) { // Fill in the glyphID (*oGlyphRecordArray)[i].glyphID = layoutRecords[i].glyphID; // Set up the relative origin of the glyph // // The real position is the x coordinate of the glyph, relative to the // beginning of the line // The baseline delta (deltaY), if any, is the y coordinate of the glyph, // relative to the baseline // (*oGlyphRecordArray)[i].relativeOrigin.x = Fix2X(layoutRecords[i].realPos); if (deltaYs == NULL) { (*oGlyphRecordArray)[i].relativeOrigin.y = 0.0; } else { (*oGlyphRecordArray)[i].relativeOrigin.y = 0.0 - Fix2X(deltaYs[i]); } } // Free the arrays of glyph information if (deltaYs != NULL) { status = ATSUDirectReleaseLayoutDataArrayPtr( NULL, kATSUDirectDataBaselineDeltaFixedArray, (void **)&deltaYs); assert(status == noErr); } status = ATSUDirectReleaseLayoutDataArrayPtr( NULL, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, (void **)&layoutRecords); assert(status == noErr); } void drawQuadratics(ATSUTextLayout iLayout, ATSUStyle iStyle, UniCharArrayOffset start, UniCharCount length, MyCurveCallbackData &data) { // boh ---------------- Fixed penX = 0; Fixed penY = 0; // ------------------- MyGlyphRecord *glyphRecordArray; ItemCount numGlyphs; ATSQuadraticNewPathUPP newPathProc; ATSQuadraticLineUPP lineProc; ATSQuadraticCurveUPP curveProc; ATSQuadraticClosePathUPP closePathProc; OSStatus status; unsigned int i; // Create the Quadratic callbacks newPathProc = NewATSQuadraticNewPathUPP(MyQuadraticNewPathProc); lineProc = NewATSQuadraticLineUPP(MyQuadraticLineProc); curveProc = NewATSQuadraticCurveUPP(MyQuadraticCurveProc); closePathProc = NewATSQuadraticClosePathUPP(MyQuadraticClosePathProc); // Get the array of glyph information GetGlyphIDsAndPositions(iLayout, start, length, &glyphRecordArray, &numGlyphs); // Loop over all the glyphs for (i = 0; i < numGlyphs; i++) { // Set up the absolute origin of the glyph data.origin.x = Fix2X(penX) + glyphRecordArray[i].relativeOrigin.x; data.origin.y = Fix2X(penY) + glyphRecordArray[i].relativeOrigin.y; // Reset state for quadratic drawing (the callbacks only do a MoveTo on the // very first segment) data.first = true; // If this is a deleted glyph (-1), don't draw it. Otherwise, go ahead. if (glyphRecordArray[i].glyphID != kATSDeletedGlyphcode) { status = ATSUGlyphGetQuadraticPaths(iStyle, glyphRecordArray[i].glyphID, newPathProc, lineProc, curveProc, closePathProc, &data, &status); assert(status == noErr); } } // Free the array of glyph information free(glyphRecordArray); // Dispose of the Quadratic callbacks DisposeATSQuadraticNewPathUPP(newPathProc); DisposeATSQuadraticLineUPP(lineProc); DisposeATSQuadraticCurveUPP(curveProc); DisposeATSQuadraticClosePathUPP(closePathProc); } //============================================================================= struct TFont::Impl { bool m_hasKerning; int m_hasVertical; // KerningPairs m_kerningPairs; ATSUStyle m_style; ATSUFontID m_fontId; ATSUTextLayout m_layout; Fixed m_size; int m_ascender; int m_descender; Impl(ATSUFontID fontId, int size); ~Impl(); // void getChar(); }; //----------------------------------------------------------------------------- TFont::TFont(ATSUFontID fontId, int size) { m_pimpl = new Impl(fontId, size); } //----------------------------------------------------------------------------- TFont::~TFont() { delete m_pimpl; } //----------------------------------------------------------------------------- TFont::Impl::Impl(ATSUFontID fontId, int size) : m_fontId(fontId), m_size(Long2Fix(size)) { OSStatus status; long response; status = Gestalt(gestaltATSUFeatures, &response); assert(response & gestaltATSUDirectAccess); status = ATSUCreateStyle(&m_style); assert(status == noErr); ATSUAttributeTag tags[2]; ByteCount sizes[2]; ATSUAttributeValuePtr values[2]; tags[0] = kATSUFontTag; sizes[0] = sizeof(ATSUFontID); values[0] = &fontId; tags[1] = kATSUSizeTag; sizes[1] = sizeof(Fixed); values[1] = &m_size; status = ATSUSetAttributes(m_style, 2, tags, sizes, values); // assert(status==noErr); UniChar dummyStr[] = {'H', 'e', 'l', 'l', 'o'}; UniCharCount length = sizeof(dummyStr) / sizeof(UniChar); status = ATSUCreateTextLayoutWithTextPtr(dummyStr, kATSUFromTextBeginning, kATSUToTextEnd, length, 1, &length, &m_style, &m_layout); // assert(status==noErr); ATSTrapezoid glyphBounds; status = ATSUGetGlyphBounds(m_layout, 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseFractionalOrigins, 1, &glyphBounds, NULL); m_ascender = -FixedToInt(glyphBounds.upperLeft.y); assert(m_ascender > 0); m_descender = -FixedToInt(glyphBounds.lowerLeft.y); assert(m_descender < 0); } //----------------------------------------------------------------------------- TFont::Impl::~Impl() {} //----------------------------------------------------------------------------- TPoint TFont::drawChar(TVectorImageP &image, wchar_t charcode, wchar_t nextCharCode) const { OSStatus status; UniChar subString[2]; subString[0] = charcode; subString[1] = 0 /*nextCharCode*/; UniCharCount length = sizeof(subString) / sizeof(UniChar); status = ATSUCreateTextLayoutWithTextPtr( subString, kATSUFromTextBeginning, kATSUToTextEnd, length, 1, &length, &(m_pimpl->m_style), &(m_pimpl->m_layout)); assert(status == noErr); MyCurveCallbackData data; data.m_image = image; drawQuadratics(m_pimpl->m_layout, m_pimpl->m_style, kATSUFromTextBeginning, kATSUToTextEnd, data); image->transform(TScale(1, -1)); image->group(0, image->getStrokeCount()); return getDistance(charcode, nextCharCode); } //----------------------------------------------------------------------------- namespace { void appDrawChar(TRasterGR8P &outImage, TFont::Impl *pimpl, wchar_t charcode) { OSStatus status; UniChar subString[2]; subString[0] = charcode; subString[1] = 0; UniCharCount length = sizeof(subString) / sizeof(UniChar); status = ATSUCreateTextLayoutWithTextPtr( subString, kATSUFromTextBeginning, kATSUToTextEnd, length, 1, &length, &(pimpl->m_style), &(pimpl->m_layout)); assert(status == noErr); ATSTrapezoid glyphBounds; status = ATSUGetGlyphBounds(pimpl->m_layout, 0, 0, kATSUFromTextBeginning, kATSUToTextEnd, kATSUseFractionalOrigins, 1, &glyphBounds, NULL); int height = FixedToInt(glyphBounds.lowerLeft.y) - FixedToInt(glyphBounds.upperLeft.y); int width = tmax(FixedToInt(glyphBounds.lowerRight.x), FixedToInt(glyphBounds.upperRight.x)) - tmin(FixedToInt(glyphBounds.lowerLeft.x), FixedToInt(glyphBounds.upperLeft.x)); outImage = TRasterGR8P(width, height); TPixelGR8 bgp; bgp.value = 255; outImage->fill(bgp); void *data = outImage->getRawData(); CGColorSpaceRef grayColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericGray); CGContextRef gContext = CGBitmapContextCreate( data, width, height, 8, width, grayColorSpace, kCGImageAlphaNone); #if defined(DEBUG) || defined(_DEBUG) int bpc = CGBitmapContextGetBitsPerComponent(gContext); if (bpc != 8) std::cout << "BitsPerComponent: " << bpc << std::endl; int bpp = CGBitmapContextGetBitsPerPixel(gContext); if (bpp != 8) std::cout << "BitsPerPixel: " << bpp << std::endl; int bytesPerRow = CGBitmapContextGetBytesPerRow(gContext); int newWidth = CGBitmapContextGetWidth(gContext); if (bytesPerRow != width || newWidth != width) std::cout << "BytesPerRow: " << bytesPerRow << " Old width= " << width << " New width= " << newWidth << std::endl; int newHeight = CGBitmapContextGetHeight(gContext); if (newHeight != height) std::cout << " Old height= " << height << " New height= " << newHeight << std::endl; assert(CGBitmapContextGetColorSpace(gContext) == grayColorSpace); #endif ATSUAttributeTag tags[1]; ByteCount sizes[1]; ATSUAttributeValuePtr values[1]; tags[0] = kATSUCGContextTag; sizes[0] = sizeof(CGContextRef); values[0] = &gContext; status = ATSUSetLayoutControls(pimpl->m_layout, 1, tags, sizes, values); assert(status == noErr); ATSUDrawText(pimpl->m_layout, kATSUFromTextBeginning, kATSUToTextEnd, 0, glyphBounds.lowerLeft.y); } } //----------------------------------------------------------------------------- TPoint TFont::drawChar(TRasterGR8P &outImage, TPoint &unused, wchar_t charcode, wchar_t nextCharCode) const { appDrawChar(outImage, m_pimpl, charcode); outImage->yMirror(); return getDistance(charcode, nextCharCode); } //----------------------------------------------------------------------------- TPoint TFont::drawChar(TRasterCM32P &outImage, TPoint &unused, int inkId, wchar_t charcode, wchar_t nextCharCode) const { TRasterGR8P grayAppImage; appDrawChar(grayAppImage, m_pimpl, charcode); int lx = grayAppImage->getLx(); int ly = grayAppImage->getLy(); outImage = TRasterCM32P(lx, ly); assert(TPixelCM32::getMaxTone() == 255); TPixelCM32 bgColor(0, 0, TPixelCM32::getMaxTone()); grayAppImage->lock(); outImage->lock(); int ty = 0; for (int gy = ly - 1; gy >= 0; --gy, ++ty) { TPixelGR8 *srcPix = grayAppImage->pixels(gy); TPixelCM32 *tarPix = outImage->pixels(ty); for (int x = 0; x < lx; ++x) { int tone = srcPix->value; if (tone == 255) *tarPix = bgColor; else *tarPix = TPixelCM32(inkId, 0, tone); ++srcPix; ++tarPix; } } grayAppImage->unlock(); outImage->unlock(); return getDistance(charcode, nextCharCode); } //----------------------------------------------------------------------------- TPoint TFont::getDistance(wchar_t firstChar, wchar_t secondChar) const { OSStatus status; UniChar subString[2]; subString[0] = firstChar; subString[1] = secondChar; UniCharCount length = sizeof(subString) / sizeof(UniChar); status = ATSUCreateTextLayoutWithTextPtr( subString, kATSUFromTextBeginning, kATSUToTextEnd, length, 1, &length, &(m_pimpl->m_style), &(m_pimpl->m_layout)); assert(status == noErr); MyGlyphRecord *glyphRecordArray; ItemCount numGlyphs; // Get the array of glyph information GetGlyphIDsAndPositions(m_pimpl->m_layout, kATSUFromTextBeginning, kATSUToTextEnd, &glyphRecordArray, &numGlyphs); assert(numGlyphs >= 2); assert(glyphRecordArray[0].relativeOrigin.x == 0); int advance = (int)(glyphRecordArray[1].relativeOrigin.x - glyphRecordArray[0].relativeOrigin.x); if (advance == 0) { subString[1] = 0; status = ATSUCreateTextLayoutWithTextPtr( subString, kATSUFromTextBeginning, kATSUToTextEnd, length, 1, &length, &(m_pimpl->m_style), &(m_pimpl->m_layout)); GetGlyphIDsAndPositions(m_pimpl->m_layout, kATSUFromTextBeginning, kATSUToTextEnd, &glyphRecordArray, &numGlyphs); advance = (int)(glyphRecordArray[1].relativeOrigin.x - glyphRecordArray[0].relativeOrigin.x); } return TPoint(advance, 0); } //----------------------------------------------------------------------------- int TFont::getMaxHeight() const { return m_pimpl->m_ascender - m_pimpl->m_descender; } //----------------------------------------------------------------------------- int TFont::getMaxWidth() const { assert(!"not implemented yet"); return 100; } //----------------------------------------------------------------------------- int TFont::getLineAscender() const { return m_pimpl->m_ascender; } //----------------------------------------------------------------------------- int TFont::getLineDescender() const { return m_pimpl->m_descender; } //----------------------------------------------------------------------------- bool TFont::hasKerning() const { return true; } //----------------------------------------------------------------------------- bool TFont::hasVertical() const { return false; } //----------------------------------------------------------------------------- #include #include typedef std::map FontFamily; typedef std::map FamilyMap; struct TFontManager::Impl { FamilyMap m_families; bool m_loaded; ATSUFontID m_currentAtsuFontId; TFont *m_currentFont; wstring m_currentFamily; wstring m_currentTypeface; int m_size; Impl() : m_currentAtsuFontId(0), m_currentFont(0), m_loaded(false), m_size(70) {} bool setFontName(ATSUFontID fontId, int platform, int script, int lang); bool addFont(ATSUFontID); void loadFontNames(); bool setFont(std::wstring family, std::wstring style); }; using namespace std; bool TFontManager::Impl::setFontName(ATSUFontID fontId, int platform, int script, int lang) { ByteCount oActualNameLength; ItemCount oFontCount; OSStatus status; char *buffer = 0; char *buffer2 = 0; // chiedo la lunhezza del Full Family Name per allocare il buffer status = ATSUFindFontName(fontId, kFontFullName, platform, script, lang, 0, 0, &oActualNameLength, 0); if (status != noErr || oActualNameLength <= 1) return false; buffer = new char[oActualNameLength + 1]; // chiedo il Full Family Name status = ATSUFindFontName(fontId, kFontFullName, platform, script, lang, oActualNameLength, buffer, &oActualNameLength, &oFontCount); if (status != noErr || oActualNameLength <= 1 || buffer[0] == '\0') { delete[] buffer; return false; } buffer[oActualNameLength] = '\0'; //------------------- // chiedo la lunhezza del Typeface Name per allocare il buffer status = ATSUFindFontName(fontId, kFontStyleName, platform, script, lang, 0, 0, &oActualNameLength, 0); if (status != noErr || oActualNameLength <= 1) { delete[] buffer; return false; } buffer2 = new char[oActualNameLength + 1]; // chiedo il Typeface Name status = ATSUFindFontName(fontId, kFontStyleName, platform, script, lang, oActualNameLength, buffer2, &oActualNameLength, &oFontCount); if (status != noErr || oActualNameLength <= 1 || buffer2[0] == '\0') { delete[] buffer; delete[] buffer2; return false; } else buffer2[oActualNameLength] = '\0'; string s_family(buffer); FontFamily &family = m_families[s_family]; family[string(buffer2)] = fontId; delete[] buffer; delete[] buffer2; return true; } bool TFontManager::Impl::addFont(ATSUFontID fontId) { int platform, script, lang; // per ottimizzare, ciclo solo sui valori // piu' comuni for (lang = -1; lang <= 0; lang++) for (platform = -1; platform <= 1; platform++) for (script = -1; script <= 0; script++) if (setFontName(fontId, platform, script, lang)) return true; // poi li provo tutti for (lang = -1; lang <= 139; lang++) for (script = -1; script <= 32; script++) for (platform = -1; platform <= 4; platform++) { // escludo quelli nel tri-ciclo for precedente. // Purtoppo si deve fare cosi: // non si puo' fare partendo con indici piu' alti nei cicli for! if (-1 <= lang && lang <= 0 && -1 <= script && script <= 0 && -1 <= platform && platform <= 1) continue; if (setFontName(fontId, platform, script, lang)) return true; } return false; } void TFontManager::Impl::loadFontNames() { if (m_loaded) return; ItemCount oFontCount, fontCount; ATSUFontCount(&oFontCount); fontCount = oFontCount; ATSUFontID *oFontIDs = new ATSUFontID[fontCount]; ATSUGetFontIDs(oFontIDs, fontCount, &oFontCount); assert(fontCount == oFontCount); for (unsigned int i = 0; i < fontCount; i++) addFont(oFontIDs[i]); delete[] oFontIDs; m_loaded = true; } bool TFontManager::Impl::setFont(std::wstring family, std::wstring typeface) { if (family == m_currentFamily && (typeface == m_currentTypeface || typeface == L"")) return false; FamilyMap::iterator family_it = m_families.find(toString(family)); if (family_it == m_families.end()) throw TFontCreationError(); m_currentFamily = family; FontFamily::iterator style_it; if (typeface == L"") { style_it = ((*family_it).second).find(toString(m_currentTypeface)); if (style_it == (*family_it).second.end()) style_it = ((*family_it).second).begin(); typeface = toWideString(style_it->first); } else style_it = ((*family_it).second).find(toString(typeface)); if (style_it == (*family_it).second.end()) throw TFontCreationError(); m_currentTypeface = typeface; m_currentAtsuFontId = (*style_it).second; return true; } //--------------------------------------------------------- TFontManager::TFontManager() { m_pimpl = new TFontManager::Impl(); } //--------------------------------------------------------- TFontManager::~TFontManager() { delete m_pimpl; } //--------------------------------------------------------- TFontManager *TFontManager::instance() { static TFontManager theManager; return &theManager; } //--------------------------------------------------------- void TFontManager::loadFontNames() { m_pimpl->loadFontNames(); } //--------------------------------------------------------- void TFontManager::setFamily(const wstring family) { bool changed = m_pimpl->setFont(family, L""); if (changed) { delete m_pimpl->m_currentFont; m_pimpl->m_currentFont = new TFont(m_pimpl->m_currentAtsuFontId, m_pimpl->m_size); } } //--------------------------------------------------------- void TFontManager::setTypeface(const wstring typeface) { bool changed = m_pimpl->setFont(m_pimpl->m_currentFamily, typeface); if (changed) { delete m_pimpl->m_currentFont; m_pimpl->m_currentFont = new TFont(m_pimpl->m_currentAtsuFontId, m_pimpl->m_size); } } //--------------------------------------------------------- void TFontManager::setSize(int size) { if (m_pimpl->m_size != size) { m_pimpl->m_size = size; delete m_pimpl->m_currentFont; m_pimpl->m_currentFont = new TFont(m_pimpl->m_currentAtsuFontId, m_pimpl->m_size); } } //--------------------------------------------------------- wstring TFontManager::getCurrentFamily() const { return m_pimpl->m_currentFamily; } //--------------------------------------------------------- wstring TFontManager::getCurrentTypeface() const { return m_pimpl->m_currentTypeface; } //--------------------------------------------------------- TFont *TFontManager::getCurrentFont() { if (m_pimpl->m_currentFont) return m_pimpl->m_currentFont; if (!m_pimpl->m_currentFont) loadFontNames(); assert(!m_pimpl->m_families.empty()); setFamily(toWideString(m_pimpl->m_families.begin()->first)); return m_pimpl->m_currentFont; } //--------------------------------------------------------- void TFontManager::getAllFamilies(vector &families) const { families.clear(); families.reserve(m_pimpl->m_families.size()); FamilyMap::iterator it = m_pimpl->m_families.begin(); for (; it != m_pimpl->m_families.end(); ++it) { families.push_back(toWideString(it->first)); } } //--------------------------------------------------------- void TFontManager::getAllTypefaces(vector &typefaces) const { typefaces.clear(); FamilyMap::iterator it_family = m_pimpl->m_families.find(toString(m_pimpl->m_currentFamily)); if (it_family == m_pimpl->m_families.end()) return; FontFamily &typefaceSet = it_family->second; typefaces.reserve(typefaceSet.size()); FontFamily::iterator it_typeface = typefaceSet.begin(); for (; it_typeface != typefaceSet.end(); ++it_typeface) { typefaces.push_back(toWideString(it_typeface->first)); } } //--------------------------------------------------------- void TFontManager::setVertical(bool vertical) {} //--------------------------------------------------------- #endif