OSDN Git Service

Add defensive code for crash in FontPlatformData
[android-x86/external-webkit.git] / WebCore / platform / graphics / android / FontPlatformDataAndroid.cpp
1 /*
2  * Copyright 2009, The Android Open Source Project
3  * Copyright (C) 2006 Apple Computer, 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  *  * 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 //This file is part of the internal font implementation.  It should not be included by anyone other than
28 // FontMac.cpp, FontWin.cpp and Font.cpp.
29
30 #include "config.h"
31 #include "FontPlatformData.h"
32
33 #ifdef SUPPORT_COMPLEX_SCRIPTS
34 #include "HarfbuzzSkia.h"
35 #endif
36 #include "SkPaint.h"
37 #include "SkTypeface.h"
38
39 //#define TRACE_FONTPLATFORMDATA_LIFE
40 //#define COUNT_FONTPLATFORMDATA_LIFE
41
42 #ifdef COUNT_FONTPLATFORMDATA_LIFE
43 static int gCount;
44 static int gMaxCount;
45
46 static void inc_count()
47 {
48     if (++gCount > gMaxCount)
49     {
50         gMaxCount = gCount;
51         SkDebugf("---------- FontPlatformData %d\n", gMaxCount);
52     }
53 }
54
55 static void dec_count() { --gCount; }
56 #else
57     #define inc_count()
58     #define dec_count()
59 #endif
60
61 #ifdef TRACE_FONTPLATFORMDATA_LIFE
62     #define trace(num)  SkDebugf("FontPlatformData%d %p %g %d %d\n", num, mTypeface, mTextSize, mFakeBold, mFakeItalic)
63 #else
64     #define trace(num)
65 #endif
66
67 namespace WebCore {
68
69 FontPlatformData::RefCountedHarfbuzzFace::~RefCountedHarfbuzzFace()
70 {
71 #ifdef SUPPORT_COMPLEX_SCRIPTS
72     HB_FreeFace(m_harfbuzzFace);
73 #endif
74 }
75
76 FontPlatformData::FontPlatformData()
77     : mTypeface(NULL), mTextSize(0), mFakeBold(false), mFakeItalic(false)
78 {
79     inc_count();
80     trace(1);
81 }
82
83 FontPlatformData::FontPlatformData(const FontPlatformData& src)
84 {
85     if (hashTableDeletedFontValue() != src.mTypeface) {
86         SkSafeRef(src.mTypeface);
87     }
88
89     mTypeface   = src.mTypeface;
90
91     mTextSize   = src.mTextSize;
92     mFakeBold   = src.mFakeBold;
93     mFakeItalic = src.mFakeItalic;
94     m_harfbuzzFace = src.m_harfbuzzFace;
95
96     inc_count();
97     trace(2);
98 }
99
100 FontPlatformData::FontPlatformData(SkTypeface* tf, float textSize, bool fakeBold, bool fakeItalic)
101     : mTypeface(tf), mTextSize(textSize), mFakeBold(fakeBold), mFakeItalic(fakeItalic)
102 {
103     if (hashTableDeletedFontValue() != mTypeface) {
104         SkSafeRef(mTypeface);
105     }
106
107     inc_count();
108     trace(3);
109 }
110
111 FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
112     : mTypeface(src.mTypeface), mTextSize(textSize), mFakeBold(src.mFakeBold), mFakeItalic(src.mFakeItalic),
113       m_harfbuzzFace(src.m_harfbuzzFace)
114 {
115     if (hashTableDeletedFontValue() != mTypeface) {
116         SkSafeRef(mTypeface);
117     }
118
119     inc_count();
120     trace(4);
121 }
122
123 FontPlatformData::FontPlatformData(float size, bool bold, bool oblique)
124     : mTypeface(NULL), mTextSize(size), mFakeBold(bold), mFakeItalic(oblique)
125 {
126     inc_count();
127     trace(5);
128 }
129
130 FontPlatformData::~FontPlatformData()
131 {
132     dec_count();
133 #ifdef TRACE_FONTPLATFORMDATA_LIFE
134     SkDebugf("----------- ~FontPlatformData\n");
135 #endif
136
137     if (hashTableDeletedFontValue() != mTypeface) {
138         SkSafeUnref(mTypeface);
139     }
140 }
141
142 FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src)
143 {
144     if (hashTableDeletedFontValue() != src.mTypeface) {
145         SkSafeRef(src.mTypeface);
146     }
147     if (hashTableDeletedFontValue() != mTypeface) {
148         SkSafeUnref(mTypeface);
149     }
150
151     mTypeface   = src.mTypeface;
152     mTextSize   = src.mTextSize;
153     mFakeBold   = src.mFakeBold;
154     mFakeItalic = src.mFakeItalic;
155     m_harfbuzzFace = src.m_harfbuzzFace;
156
157     return *this;
158 }
159
160 void FontPlatformData::setupPaint(SkPaint* paint) const
161 {
162     float ts = mTextSize;
163     if (!(ts > 0))
164         ts = 12;
165
166     if (hashTableDeletedFontValue() == mTypeface)
167         paint->setTypeface(0);
168     else
169         paint->setTypeface(mTypeface);
170
171     paint->setAntiAlias(true);
172     paint->setSubpixelText(true);
173     paint->setHinting(SkPaint::kSlight_Hinting);
174     paint->setTextSize(SkFloatToScalar(ts));
175     paint->setFakeBoldText(mFakeBold);
176     paint->setTextSkewX(mFakeItalic ? -SK_Scalar1/4 : 0);
177 #ifndef SUPPORT_COMPLEX_SCRIPTS
178     paint->setTextEncoding(SkPaint::kUTF16_TextEncoding);
179 #endif
180 }
181
182 uint32_t FontPlatformData::uniqueID() const
183 {
184     if (hashTableDeletedFontValue() == mTypeface)
185         return SkTypeface::UniqueID(0);
186     else
187         return SkTypeface::UniqueID(mTypeface);
188 }
189
190 bool FontPlatformData::operator==(const FontPlatformData& a) const
191 {
192     return  mTypeface == a.mTypeface &&
193             mTextSize == a.mTextSize &&
194             mFakeBold == a.mFakeBold &&
195             mFakeItalic == a.mFakeItalic;
196 }
197
198 unsigned FontPlatformData::hash() const
199 {
200     unsigned h;
201
202     if (hashTableDeletedFontValue() == mTypeface) {
203         h = reinterpret_cast<unsigned>(mTypeface);
204     } else {
205         h = SkTypeface::UniqueID(mTypeface);
206     }
207
208     uint32_t sizeAsInt = *reinterpret_cast<const uint32_t*>(&mTextSize);
209
210     h ^= 0x01010101 * (((int)mFakeBold << 1) | (int)mFakeItalic);
211     h ^= sizeAsInt;
212     return h;
213 }
214
215 bool FontPlatformData::isFixedPitch() const
216 {
217     if (mTypeface && (mTypeface != hashTableDeletedFontValue()))
218         return mTypeface->isFixedWidth();
219     else
220         return false;
221 }
222
223 HB_FaceRec_* FontPlatformData::harfbuzzFace() const
224 {
225 #ifdef SUPPORT_COMPLEX_SCRIPTS
226     if (!m_harfbuzzFace)
227         m_harfbuzzFace = RefCountedHarfbuzzFace::create(
228             HB_NewFace(const_cast<FontPlatformData*>(this), harfbuzzSkiaGetTable));
229
230     return m_harfbuzzFace->face();
231 #else
232     return NULL;
233 #endif
234 }
235 }