PageRenderTime 24ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/src/qt/qtwebkit/Source/WebCore/platform/graphics/SimpleFontData.cpp

https://gitlab.com/x33n/phantomjs
C++ | 304 lines | 226 code | 38 blank | 40 comment | 39 complexity | 51c2cb5d5d3b3fe02c5da069a4dbe459 MD5 | raw file
  1. /*
  2. * Copyright (C) 2005, 2008, 2010 Apple Inc. All rights reserved.
  3. * Copyright (C) 2006 Alexey Proskuryakov
  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. #include "config.h"
  30. #include "SimpleFontData.h"
  31. #include "Font.h"
  32. #include "FontCache.h"
  33. #include <wtf/MathExtras.h>
  34. #if ENABLE(OPENTYPE_VERTICAL)
  35. #include "OpenTypeVerticalData.h"
  36. #endif
  37. using namespace std;
  38. namespace WebCore {
  39. const float smallCapsFontSizeMultiplier = 0.7f;
  40. const float emphasisMarkFontSizeMultiplier = 0.5f;
  41. SimpleFontData::SimpleFontData(const FontPlatformData& platformData, bool isCustomFont, bool isLoading, bool isTextOrientationFallback)
  42. : m_maxCharWidth(-1)
  43. , m_avgCharWidth(-1)
  44. , m_platformData(platformData)
  45. , m_treatAsFixedPitch(false)
  46. , m_isCustomFont(isCustomFont)
  47. , m_isLoading(isLoading)
  48. , m_isTextOrientationFallback(isTextOrientationFallback)
  49. , m_isBrokenIdeographFallback(false)
  50. #if ENABLE(OPENTYPE_VERTICAL)
  51. , m_verticalData(0)
  52. #endif
  53. , m_hasVerticalGlyphs(false)
  54. {
  55. platformInit();
  56. platformGlyphInit();
  57. platformCharWidthInit();
  58. #if ENABLE(OPENTYPE_VERTICAL)
  59. if (platformData.orientation() == Vertical && !isTextOrientationFallback) {
  60. m_verticalData = platformData.verticalData();
  61. m_hasVerticalGlyphs = m_verticalData.get() && m_verticalData->hasVerticalMetrics();
  62. }
  63. #endif
  64. }
  65. SimpleFontData::SimpleFontData(PassOwnPtr<AdditionalFontData> fontData, float fontSize, bool syntheticBold, bool syntheticItalic)
  66. : m_platformData(FontPlatformData(fontSize, syntheticBold, syntheticItalic))
  67. , m_fontData(fontData)
  68. , m_treatAsFixedPitch(false)
  69. , m_isCustomFont(true)
  70. , m_isLoading(false)
  71. , m_isTextOrientationFallback(false)
  72. , m_isBrokenIdeographFallback(false)
  73. #if ENABLE(OPENTYPE_VERTICAL)
  74. , m_verticalData(0)
  75. #endif
  76. , m_hasVerticalGlyphs(false)
  77. {
  78. m_fontData->initializeFontData(this, fontSize);
  79. }
  80. // Estimates of avgCharWidth and maxCharWidth for platforms that don't support accessing these values from the font.
  81. void SimpleFontData::initCharWidths()
  82. {
  83. GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
  84. // Treat the width of a '0' as the avgCharWidth.
  85. if (m_avgCharWidth <= 0.f && glyphPageZero) {
  86. static const UChar32 digitZeroChar = '0';
  87. Glyph digitZeroGlyph = glyphPageZero->glyphDataForCharacter(digitZeroChar).glyph;
  88. if (digitZeroGlyph)
  89. m_avgCharWidth = widthForGlyph(digitZeroGlyph);
  90. }
  91. // If we can't retrieve the width of a '0', fall back to the x height.
  92. if (m_avgCharWidth <= 0.f)
  93. m_avgCharWidth = m_fontMetrics.xHeight();
  94. if (m_maxCharWidth <= 0.f)
  95. m_maxCharWidth = max(m_avgCharWidth, m_fontMetrics.floatAscent());
  96. }
  97. void SimpleFontData::platformGlyphInit()
  98. {
  99. GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
  100. if (!glyphPageZero) {
  101. LOG_ERROR("Failed to get glyph page zero.");
  102. m_spaceGlyph = 0;
  103. m_spaceWidth = 0;
  104. m_zeroGlyph = 0;
  105. m_adjustedSpaceWidth = 0;
  106. determinePitch();
  107. m_zeroWidthSpaceGlyph = 0;
  108. m_missingGlyphData.fontData = this;
  109. m_missingGlyphData.glyph = 0;
  110. return;
  111. }
  112. m_zeroWidthSpaceGlyph = glyphPageZero->glyphDataForCharacter(0).glyph;
  113. // Nasty hack to determine if we should round or ceil space widths.
  114. // If the font is monospace or fake monospace we ceil to ensure that
  115. // every character and the space are the same width. Otherwise we round.
  116. m_spaceGlyph = glyphPageZero->glyphDataForCharacter(' ').glyph;
  117. float width = widthForGlyph(m_spaceGlyph);
  118. m_spaceWidth = width;
  119. m_zeroGlyph = glyphPageZero->glyphDataForCharacter('0').glyph;
  120. m_fontMetrics.setZeroWidth(widthForGlyph(m_zeroGlyph));
  121. determinePitch();
  122. m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width);
  123. // Force the glyph for ZERO WIDTH SPACE to have zero width, unless it is shared with SPACE.
  124. // Helvetica is an example of a non-zero width ZERO WIDTH SPACE glyph.
  125. // See <http://bugs.webkit.org/show_bug.cgi?id=13178>
  126. // Ask for the glyph for 0 to avoid paging in ZERO WIDTH SPACE. Control characters, including 0,
  127. // are mapped to the ZERO WIDTH SPACE glyph.
  128. if (m_zeroWidthSpaceGlyph == m_spaceGlyph) {
  129. m_zeroWidthSpaceGlyph = 0;
  130. LOG_ERROR("Font maps SPACE and ZERO WIDTH SPACE to the same glyph. Glyph width will not be overridden.");
  131. }
  132. m_missingGlyphData.fontData = this;
  133. m_missingGlyphData.glyph = 0;
  134. }
  135. SimpleFontData::~SimpleFontData()
  136. {
  137. if (!m_fontData)
  138. platformDestroy();
  139. if (isCustomFont())
  140. GlyphPageTreeNode::pruneTreeCustomFontData(this);
  141. else
  142. GlyphPageTreeNode::pruneTreeFontData(this);
  143. }
  144. const SimpleFontData* SimpleFontData::fontDataForCharacter(UChar32) const
  145. {
  146. return this;
  147. }
  148. Glyph SimpleFontData::glyphForCharacter(UChar32 character) const
  149. {
  150. GlyphPageTreeNode* node = GlyphPageTreeNode::getRootChild(this, character / GlyphPage::size);
  151. return node->page() ? node->page()->glyphAt(character % GlyphPage::size) : 0;
  152. }
  153. bool SimpleFontData::isSegmented() const
  154. {
  155. return false;
  156. }
  157. PassRefPtr<SimpleFontData> SimpleFontData::verticalRightOrientationFontData() const
  158. {
  159. if (!m_derivedFontData)
  160. m_derivedFontData = DerivedFontData::create(isCustomFont());
  161. if (!m_derivedFontData->verticalRightOrientation) {
  162. FontPlatformData verticalRightPlatformData(m_platformData);
  163. verticalRightPlatformData.setOrientation(Horizontal);
  164. m_derivedFontData->verticalRightOrientation = create(verticalRightPlatformData, isCustomFont(), false, true);
  165. }
  166. return m_derivedFontData->verticalRightOrientation;
  167. }
  168. PassRefPtr<SimpleFontData> SimpleFontData::uprightOrientationFontData() const
  169. {
  170. if (!m_derivedFontData)
  171. m_derivedFontData = DerivedFontData::create(isCustomFont());
  172. if (!m_derivedFontData->uprightOrientation)
  173. m_derivedFontData->uprightOrientation = create(m_platformData, isCustomFont(), false, true);
  174. return m_derivedFontData->uprightOrientation;
  175. }
  176. PassRefPtr<SimpleFontData> SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
  177. {
  178. if (!m_derivedFontData)
  179. m_derivedFontData = DerivedFontData::create(isCustomFont());
  180. if (!m_derivedFontData->smallCaps)
  181. m_derivedFontData->smallCaps = createScaledFontData(fontDescription, smallCapsFontSizeMultiplier);
  182. return m_derivedFontData->smallCaps;
  183. }
  184. PassRefPtr<SimpleFontData> SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const
  185. {
  186. if (!m_derivedFontData)
  187. m_derivedFontData = DerivedFontData::create(isCustomFont());
  188. if (!m_derivedFontData->emphasisMark)
  189. m_derivedFontData->emphasisMark = createScaledFontData(fontDescription, emphasisMarkFontSizeMultiplier);
  190. return m_derivedFontData->emphasisMark;
  191. }
  192. PassRefPtr<SimpleFontData> SimpleFontData::brokenIdeographFontData() const
  193. {
  194. if (!m_derivedFontData)
  195. m_derivedFontData = DerivedFontData::create(isCustomFont());
  196. if (!m_derivedFontData->brokenIdeograph) {
  197. m_derivedFontData->brokenIdeograph = create(m_platformData, isCustomFont(), false);
  198. m_derivedFontData->brokenIdeograph->m_isBrokenIdeographFallback = true;
  199. }
  200. return m_derivedFontData->brokenIdeograph;
  201. }
  202. PassRefPtr<SimpleFontData> SimpleFontData::nonSyntheticItalicFontData() const
  203. {
  204. if (!m_derivedFontData)
  205. m_derivedFontData = DerivedFontData::create(isCustomFont());
  206. if (!m_derivedFontData->nonSyntheticItalic) {
  207. FontPlatformData nonSyntheticItalicFontPlatformData(m_platformData);
  208. #if PLATFORM(MAC)
  209. nonSyntheticItalicFontPlatformData.m_syntheticOblique = false;
  210. #endif
  211. m_derivedFontData->nonSyntheticItalic = create(nonSyntheticItalicFontPlatformData, isCustomFont(), false, true);
  212. }
  213. return m_derivedFontData->nonSyntheticItalic;
  214. }
  215. #ifndef NDEBUG
  216. String SimpleFontData::description() const
  217. {
  218. if (isSVGFont())
  219. return "[SVG font]";
  220. if (isCustomFont())
  221. return "[custom font]";
  222. return platformData().description();
  223. }
  224. #endif
  225. PassOwnPtr<SimpleFontData::DerivedFontData> SimpleFontData::DerivedFontData::create(bool forCustomFont)
  226. {
  227. return adoptPtr(new DerivedFontData(forCustomFont));
  228. }
  229. SimpleFontData::DerivedFontData::~DerivedFontData()
  230. {
  231. if (!forCustomFont)
  232. return;
  233. if (smallCaps)
  234. GlyphPageTreeNode::pruneTreeCustomFontData(smallCaps.get());
  235. if (emphasisMark)
  236. GlyphPageTreeNode::pruneTreeCustomFontData(emphasisMark.get());
  237. if (brokenIdeograph)
  238. GlyphPageTreeNode::pruneTreeCustomFontData(brokenIdeograph.get());
  239. if (verticalRightOrientation)
  240. GlyphPageTreeNode::pruneTreeCustomFontData(verticalRightOrientation.get());
  241. if (uprightOrientation)
  242. GlyphPageTreeNode::pruneTreeCustomFontData(uprightOrientation.get());
  243. #if PLATFORM(MAC)
  244. if (compositeFontReferences) {
  245. CFDictionaryRef dictionary = CFDictionaryRef(compositeFontReferences.get());
  246. CFIndex count = CFDictionaryGetCount(dictionary);
  247. if (count > 0) {
  248. Vector<SimpleFontData*, 2> stash(count);
  249. SimpleFontData** fonts = stash.data();
  250. CFDictionaryGetKeysAndValues(dictionary, 0, (const void **)fonts);
  251. while (count-- > 0 && *fonts) {
  252. RefPtr<SimpleFontData> afont = adoptRef(*fonts++);
  253. GlyphPageTreeNode::pruneTreeCustomFontData(afont.get());
  254. }
  255. }
  256. }
  257. #endif
  258. }
  259. PassRefPtr<SimpleFontData> SimpleFontData::createScaledFontData(const FontDescription& fontDescription, float scaleFactor) const
  260. {
  261. // FIXME: Support scaled fonts that used AdditionalFontData.
  262. if (m_fontData)
  263. return 0;
  264. return platformCreateScaledFontData(fontDescription, scaleFactor);
  265. }
  266. } // namespace WebCore