]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/samples/layout/GDIFontInstance.cpp
ICU-551.51.4.tar.gz
[apple/icu.git] / icuSources / samples / layout / GDIFontInstance.cpp
index 8aa928a0bdad4f48cba506a7ffa69e80787720df..5e94e5d2ffbd2d2522a33caae9b08ba583bf9b0d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *******************************************************************************
  *
- *   Copyright (C) 1999-2003, International Business Machines
+ *   Copyright (C) 1999-2008, International Business Machines
  *   Corporation and others.  All Rights Reserved.
  *
  *******************************************************************************
@@ -55,6 +55,8 @@ void GDISurface::drawGlyphs(const LEFontInstance *font, const LEGlyphID *glyphs,
 {
     TTGlyphID *ttGlyphs = LE_NEW_ARRAY(TTGlyphID, count);
     le_int32  *dx = LE_NEW_ARRAY(le_int32, count);
+    float     *ps = LE_NEW_ARRAY(float, count * 2 + 2);
+    le_int32   out = 0;
     RECT clip;
 
     clip.top    = 0;
@@ -63,13 +65,15 @@ void GDISurface::drawGlyphs(const LEFontInstance *font, const LEGlyphID *glyphs,
     clip.right  = width;
 
     for (le_int32 g = 0; g < count; g += 1) {
-        ttGlyphs[g] = (TTGlyphID) LE_GET_GLYPH(glyphs[g]);
-
-        if (ttGlyphs[g] == 0xFFFF || ttGlyphs[g] == 0xFFFE) {
-            ttGlyphs[g] = 0x0002;
+        TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyphs[g]);
+
+        if (ttGlyph < 0xFFFE) {
+            ttGlyphs[out] = ttGlyph;
+            dx[out] = (le_int32) (positions[g * 2 + 2] - positions[g * 2]);
+            ps[out * 2] = positions[g * 2];
+            ps[out * 2 + 1] = positions[g * 2 + 1];
+            out += 1;
         }
-
-        dx[g] = (le_int32) (positions[g * 2 + 2] - positions[g * 2]);
     }
 
     le_int32 dyStart, dyEnd;
@@ -78,20 +82,21 @@ void GDISurface::drawGlyphs(const LEFontInstance *font, const LEGlyphID *glyphs,
 
     dyStart = dyEnd = 0;
 
-    while (dyEnd < count) {
-        float yOffset = positions[dyStart * 2 + 1];
-        float xOffset = positions[dyStart * 2];
+    while (dyEnd < out) {
+        float yOffset = ps[dyStart * 2 + 1];
+        float xOffset = ps[dyStart * 2];
 
-        while (dyEnd < count && yOffset == positions[dyEnd * 2 + 1]) {
+        while (dyEnd < out && yOffset == ps[dyEnd * 2 + 1]) {
             dyEnd += 1;
         }
 
         ExtTextOut(fHdc, x + (le_int32) xOffset, y + (le_int32) yOffset - font->getAscent(), ETO_CLIPPED | ETO_GLYPH_INDEX, &clip,
-            &ttGlyphs[dyStart], dyEnd - dyStart, (INT *) &dx[dyStart]);
+            (LPCWSTR) &ttGlyphs[dyStart], dyEnd - dyStart, (INT *) &dx[dyStart]);
 
         dyStart = dyEnd;
     }
 
+    LE_DELETE_ARRAY(ps);
     LE_DELETE_ARRAY(dx);
     LE_DELETE_ARRAY(ttGlyphs);
 }
@@ -245,15 +250,39 @@ GDIFontInstance::GDIFontInstance(GDISurface *surface, const char *faceName, le_i
 
     UINT ret = GetOutlineTextMetrics(hdc, sizeof otm, &otm);
 
-    if (ret == 0) {
-        status = LE_MISSING_FONT_TABLE_ERROR;
-        goto restore;
-    }
+    if (ret != 0) {
+        fUnitsPerEM = otm.otmEMSquare;
+        fAscent  = otm.otmTextMetrics.tmAscent;
+        fDescent = otm.otmTextMetrics.tmDescent;
+        fLeading = otm.otmTextMetrics.tmExternalLeading;
+    } else {
+        const HEADTable *headTable = NULL;
+        const HHEATable *hheaTable = NULL;
+
+        // read unitsPerEm from 'head' table
+        headTable = (const HEADTable *) readFontTable(LE_HEAD_TABLE_TAG);
+
+        if (headTable == NULL) {
+            status = LE_MISSING_FONT_TABLE_ERROR;
+            goto restore;
+        }
 
-    fUnitsPerEM = otm.otmEMSquare;
-    fAscent  = otm.otmTextMetrics.tmAscent;
-    fDescent = otm.otmTextMetrics.tmDescent;
-    fLeading = otm.otmTextMetrics.tmExternalLeading;
+        fUnitsPerEM   = SWAPW(headTable->unitsPerEm);
+        freeFontTable((const void *)headTable);
+
+        hheaTable = (HHEATable *) readFontTable(LE_HHEA_TABLE_TAG);
+
+        if (hheaTable == NULL) {
+            status = LE_MISSING_FONT_TABLE_ERROR;
+            goto restore;
+        }
+
+        fAscent  = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent));
+        fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent));
+        fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap));
+
+        freeFontTable((const void *) hheaTable);
+    }
 
     status = initMapper();
 
@@ -367,7 +396,7 @@ le_bool GDIFontInstance::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LE
 
     return result;
 #else
-    return false;
+    return FALSE;
 #endif
 }