Home | History | Annotate | Download | only in wince
      1 /*
      2  * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
      3  * Copyright (C) 2007-2009 Torch Mobile, Inc.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      9  * 1.  Redistributions of source code must retain the above copyright
     10  *     notice, this list of conditions and the following disclaimer.
     11  * 2.  Redistributions in binary form must reproduce the above copyright
     12  *     notice, this list of conditions and the following disclaimer in the
     13  *     documentation and/or other materials provided with the distribution.
     14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     15  *     its contributors may be used to endorse or promote products derived
     16  *     from this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #include "config.h"
     31 #include "SimpleFontData.h"
     32 
     33 #include "FloatRect.h"
     34 #include "Font.h"
     35 #include "FontCache.h"
     36 #include "FontDescription.h"
     37 #include <mlang.h>
     38 #include <wtf/MathExtras.h>
     39 
     40 namespace WebCore {
     41 
     42 extern HDC g_screenDC;
     43 
     44 void SimpleFontData::platformInit()
     45 {
     46     if (!m_platformData.isValid())
     47         return;
     48 
     49     const TEXTMETRIC& tm = m_platformData.metrics();
     50     m_isSystemFont = m_platformData.isSystemFont();
     51 
     52     float ascent = (tm.tmAscent * m_platformData.size() + 36) / 72.0f;
     53     float descent = (tm.tmDescent * m_platformData.size() + 36) / 72.0f;
     54     float lineGap = (tm.tmExternalLeading * m_platformData.size() + 36) / 72.0f;
     55     m_fontMetrics.setAscent(ascent);
     56     m_fontMetrics.setDescent(descent);
     57     m_fontMetrics.setLineGap(lineGap);
     58     m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
     59     m_fontMetrics.setXHeight(ascent * 0.56f);
     60 }
     61 
     62 void SimpleFontData::platformDestroy()
     63 {
     64 }
     65 
     66 SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const
     67 {
     68     FontDescription fontDesc(fontDescription);
     69     fontDesc.setComputedSize(lroundf(scaleFactor * fontDesc.computedSize()));
     70     fontDesc.setSpecifiedSize(lroundf(scaleFactor * fontDesc.specifiedSize()));
     71     fontDesc.setKeywordSize(lroundf(scaleFactor * fontDesc.keywordSize()));
     72     FontPlatformData* result = fontCache()->getCachedFontPlatformData(fontDesc, m_platformData.family());
     73     return result ? new SimpleFontData(*result) : 0;
     74 }
     75 
     76 SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
     77 {
     78     if (!m_derivedFontData)
     79         m_derivedFontData = DerivedFontData::create(isCustomFont());
     80     if (!m_derivedFontData->smallCaps)
     81         m_derivedFontData->smallCaps = scaledFontData(fontDescription, .7);
     82 
     83     return m_derivedFontData->smallCaps.get();
     84 }
     85 
     86 SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
     87 {
     88     if (!m_derivedFontData)
     89         m_derivedFontData = DerivedFontData::create(isCustomFont());
     90     if (!m_derivedFontData->emphasisMark)
     91         m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5);
     92 
     93     return m_derivedFontData->emphasisMark.get();
     94 }
     95 
     96 DWORD getKnownFontCodePages(const wchar_t* family);
     97 
     98 bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
     99 {
    100     if (m_platformData.isDisabled())
    101         return true;
    102 
    103     // FIXME: Microsoft documentation seems to imply that characters can be output using a given font and DC
    104     // merely by testing code page intersection.  This seems suspect though.  Can't a font only partially
    105     // cover a given code page?
    106 
    107     // FIXME: in the case that we failed to get the interface, still use the font.
    108 #if defined(IMLANG_FONT_LINK) && (IMLANG_FONT_LINK == 2)
    109     IMLangFontLink2* langFontLink = fontCache()->getFontLinkInterface();
    110 #else
    111     IMLangFontLink* langFontLink = fontCache()->getFontLinkInterface();
    112 #endif
    113     if (!langFontLink)
    114         return true;
    115 
    116     DWORD fontCodePages = m_platformData.codePages();
    117     if (!fontCodePages)
    118         return false;
    119 
    120     DWORD acpCodePages = 0;
    121     langFontLink->CodePageToCodePages(CP_ACP, &acpCodePages);
    122 
    123     DWORD actualCodePages;
    124     long numCharactersProcessed;
    125     while (length) {
    126         langFontLink->GetStrCodePages(characters, length, acpCodePages, &actualCodePages, &numCharactersProcessed);
    127         if (actualCodePages && !(actualCodePages & fontCodePages))
    128             return false;
    129 
    130         length -= numCharactersProcessed;
    131         characters += numCharactersProcessed;
    132     }
    133 
    134     return true;
    135 }
    136 
    137 void SimpleFontData::determinePitch()
    138 {
    139     if (!m_platformData.isValid())
    140         return;
    141 
    142     const TEXTMETRIC& tm = m_platformData.metrics();
    143 
    144     // Yes, this looks backwards, but the fixed pitch bit is actually set if the font
    145     // is *not* fixed pitch.  Unbelievable but true.
    146     m_treatAsFixedPitch = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH);
    147 }
    148 
    149 FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const
    150 {
    151     return FloatRect();
    152 }
    153 
    154 float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
    155 {
    156     if (m_platformData.isDisabled())
    157         return 0;
    158 
    159     HGDIOBJ hOldFont = SelectObject(g_screenDC, m_platformData.hfont());
    160 
    161     SIZE fontSize;
    162     wchar_t c = glyph;
    163     GetTextExtentPoint32(g_screenDC, &c, 1, &fontSize);
    164 
    165     SelectObject(g_screenDC, hOldFont);
    166 
    167     return (float)fontSize.cx * (float)m_platformData.size() / 72.f;
    168 }
    169 
    170 
    171 void SimpleFontData::platformCharWidthInit()
    172 {
    173     if (!m_platformData.isValid())
    174         return;
    175 
    176     const TEXTMETRIC& tm = m_platformData.metrics();
    177     m_avgCharWidth = (tm.tmAveCharWidth * m_platformData.size() + 36) / 72;
    178     m_maxCharWidth = (tm.tmMaxCharWidth * m_platformData.size() + 36) / 72;
    179 }
    180 
    181 } // namespace WebCore
    182