1/*
2 * Copyright 2009, The Android Open Source Project
3 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
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 *  * Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 *  * Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28
29#include "EmojiFont.h"
30#include "Font.h"
31#include "FontCache.h"
32#include "SimpleFontData.h"
33#include "FloatRect.h"
34#include "FontDescription.h"
35#include "SkFontHost.h"
36#include "SkPaint.h"
37#include "SkTypeface.h"
38#include "SkTime.h"
39
40using namespace android;
41
42namespace WebCore {
43
44void SimpleFontData::platformInit()
45{
46    SkPaint  paint;
47    SkPaint::FontMetrics skiaFontMetrics;
48
49    m_platformData.setupPaint(&paint);
50    paint.getFontMetrics(&skiaFontMetrics);
51
52    float d = SkScalarToFloat(skiaFontMetrics.fDescent);
53    float s = SkScalarToFloat(skiaFontMetrics.fDescent - skiaFontMetrics.fAscent);
54    float a = s - d;
55
56    m_fontMetrics.setAscent(a);
57    m_fontMetrics.setDescent(d);
58    m_fontMetrics.setXHeight(SkScalarToFloat(-skiaFontMetrics.fAscent) * 0.56f);   // hack I stole from the window's port
59    float lineGap = SkScalarToFloat(skiaFontMetrics.fLeading);
60    if (platformData().orientation() == Vertical && lineGap == 0) {
61        lineGap = skiaFontMetrics.fAvgCharWidth * 0.56f;
62    }
63    m_fontMetrics.setLineGap(lineGap);
64    m_fontMetrics.setLineSpacing(a + d + lineGap);
65
66    if (platformData().orientation() == Vertical && !isTextOrientationFallback()) {
67        static const uint32_t vheaTag = SkSetFourByteTag('v', 'h', 'e', 'a');
68        static const uint32_t vorgTag = SkSetFourByteTag('V', 'O', 'R', 'G');
69        const SkFontID fontID = m_platformData.uniqueID();
70        size_t vheaSize = SkFontHost::GetTableSize(fontID, vheaTag);
71        size_t vorgSize = SkFontHost::GetTableSize(fontID, vorgTag);
72        if ((vheaSize > 0) || (vorgSize > 0))
73            m_hasVerticalGlyphs = true;
74    }
75}
76
77void SimpleFontData::platformCharWidthInit()
78{
79    m_avgCharWidth = 0.f;
80    m_maxCharWidth = 0.f;
81    initCharWidths();
82}
83
84void SimpleFontData::platformDestroy()
85{
86}
87
88SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
89{
90    if (!m_derivedFontData)
91        m_derivedFontData = DerivedFontData::create(isCustomFont());
92    if (!m_derivedFontData->smallCaps)
93        m_derivedFontData->smallCaps = new SimpleFontData(FontPlatformData(m_platformData, fontDescription.computedSize() * 0.7f));
94
95    return m_derivedFontData->smallCaps.get();
96}
97
98SimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
99{
100    if (!m_derivedFontData)
101        m_derivedFontData = DerivedFontData::create(isCustomFont());
102    if (!m_derivedFontData->emphasisMark)
103        m_derivedFontData->emphasisMark = new SimpleFontData(FontPlatformData(m_platformData, fontDescription.computedSize() * 0.5f));
104
105    return m_derivedFontData->emphasisMark.get();
106}
107
108bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
109{
110    SkPaint     paint;
111
112    m_platformData.setupPaint(&paint);
113    paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
114    return paint.containsText(characters, length << 1);
115}
116
117void SimpleFontData::determinePitch()
118{
119    m_treatAsFixedPitch = m_platformData.isFixedPitch();
120}
121
122FloatRect SimpleFontData::platformBoundsForGlyph(Glyph) const
123{
124    return FloatRect();
125}
126
127float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
128{
129    SkASSERT(sizeof(glyph) == 2);   // compile-time assert
130
131    SkPaint  paint;
132
133    m_platformData.setupPaint(&paint);
134
135    float advanceWidth;
136    if (EmojiFont::IsEmojiGlyph(glyph))
137        advanceWidth = EmojiFont::GetAdvanceWidth(glyph, paint);
138    else {
139        paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
140        advanceWidth = SkScalarToFloat(paint.measureText(&glyph, 2));
141    }
142    return advanceWidth;
143}
144
145
146}
147