+2007-12-19 Dave Hyatt <hyatt@apple.com>
+
+ Add support for GDI text rendering to WebKit.
+
+ Reviewed by mitz
+
+ * css/CSSStyleSelector.cpp:
+ (WebCore::CSSStyleSelector::applyProperty):
+ * dom/Document.cpp:
+ (WebCore::Document::recalcStyle):
+ * page/Settings.cpp:
+ (WebCore::Settings::setFontRenderingMode):
+ (WebCore::Settings::fontRenderingMode):
+ * page/Settings.h:
+ * platform/graphics/Font.h:
+ (WebCore::Font::renderingMode):
+ * platform/graphics/FontCache.cpp:
+ (WebCore::FontPlatformDataCacheKey::FontPlatformDataCacheKey):
+ (WebCore::FontPlatformDataCacheKey::operator==):
+ (WebCore::computeHash):
+ (WebCore::FontCache::getCachedFontPlatformData):
+ * platform/graphics/FontDescription.h:
+ (WebCore::):
+ (WebCore::FontDescription::FontDescription):
+ (WebCore::FontDescription::renderingMode):
+ (WebCore::FontDescription::setRenderingMode):
+ (WebCore::FontDescription::operator==):
+ * platform/graphics/GraphicsContext.h:
+ * platform/graphics/win/FontCacheWin.cpp:
+ (WebCore::FontCache::fontExists):
+ (WebCore::FontCache::createFontPlatformData):
+ * platform/graphics/win/FontDataWin.cpp:
+ (WebCore::FontData::platformInit):
+ (WebCore::FontData::smallCapsFontData):
+ (WebCore::FontData::containsCharacters):
+ (WebCore::FontData::determinePitch):
+ (WebCore::FontData::platformWidthForGlyph):
+ * platform/graphics/win/FontPlatformData.h:
+ (WebCore::FontPlatformData::FontPlatformData):
+ (WebCore::FontPlatformData::useGDI):
+ (WebCore::FontPlatformData::operator==):
+ * platform/graphics/win/FontPlatformDataWin.cpp:
+ (WebCore::FontPlatformData::FontPlatformData):
+ * platform/graphics/win/FontWin.cpp:
+ (WebCore::Font::drawGlyphs):
+ * platform/graphics/win/IconWin.cpp:
+ (WebCore::Icon::paint):
+ * platform/win/GraphicsContextWin.cpp:
+ (WebCore::GraphicsContext::getWindowsContext):
+ (WebCore::GraphicsContext::releaseWindowsContext):
+ * platform/win/UniscribeController.cpp:
+ (WebCore::UniscribeController::shapeAndPlaceItem):
+ * platform/win/UniscribeController.h:
+ * plugins/win/PluginViewWin.cpp:
+ (WebCore::PluginViewWin::paint):
+
2007-12-19 Sven Herzberg <sven@imendio.com>
Reviewed by Alp Toker.
if (style->setFontDescription(fontDescription))
fontDirty = true;
} else if (isInitial) {
+ Settings* settings = m_document->settings();
FontDescription fontDescription;
fontDescription.setGenericFamily(FontDescription::StandardFamily);
+ fontDescription.setRenderingMode(settings->fontRenderingMode());
+ fontDescription.setUsePrinterFont(m_document->printing());
const AtomicString& standardFontFamily = m_document->settings()->standardFontFamily();
if (!standardFontFamily.isEmpty()) {
fontDescription.firstFamily().setFamily(standardFontFamily);
FontDescription fontDescription;
fontDescription.setUsePrinterFont(printing());
if (Settings* settings = this->settings()) {
+ fontDescription.setRenderingMode(settings->fontRenderingMode());
if (printing() && !settings->shouldPrintBackgrounds())
_style->setForceBackgroundsToWhite(true);
const AtomicString& stdfont = settings->standardFontFamily();
#endif
}
+void Settings::setFontRenderingMode(FontRenderingMode mode)
+{
+ if (m_fontRenderingMode == mode)
+ return;
+ m_fontRenderingMode = mode;
+ setNeedsReapplyStylesInAllFrames(m_page);
+}
+
+FontRenderingMode Settings::fontRenderingMode() const
+{
+ return m_fontRenderingMode;
+}
+
} // namespace WebCore
#include "AtomicString.h"
#include "KURL.h"
+#include "FontDescription.h"
namespace WebCore {
void setDefaultDatabaseOriginQuota(unsigned long long);
unsigned long long defaultDatabaseOriginQuota() const;
+ void setFontRenderingMode(FontRenderingMode mode);
+ FontRenderingMode fontRenderingMode() const;
+
private:
Page* m_page;
bool m_forceFTPDirectoryListings : 1;
bool m_developerExtrasEnabled : 1;
bool m_authorAndUserStylesEnabled : 1;
+ FontRenderingMode m_fontRenderingMode : 1;
};
} // namespace WebCore
bool isFixedPitch() const;
bool isPrinterFont() const { return m_fontDescription.usePrinterFont(); }
+
+ FontRenderingMode renderingMode() const { return m_fontDescription.renderingMode(); }
FontFamily& firstFamily() { return m_fontDescription.firstFamily(); }
const FontFamily& family() const { return m_fontDescription.family(); }
struct FontPlatformDataCacheKey {
FontPlatformDataCacheKey(const AtomicString& family = AtomicString(), unsigned size = 0, bool bold = false, bool italic = false,
- bool isPrinterFont = false)
+ bool isPrinterFont = false, FontRenderingMode renderingMode = NormalRenderingMode)
: m_family(family)
, m_size(size)
, m_bold(bold)
, m_italic(italic)
, m_printerFont(isPrinterFont)
+ , m_renderingMode(renderingMode)
{
}
bool operator==(const FontPlatformDataCacheKey& other) const
{
return equalIgnoringCase(m_family, other.m_family) && m_size == other.m_size &&
- m_bold == other.m_bold && m_italic == other.m_italic && m_printerFont == other.m_printerFont;
+ m_bold == other.m_bold && m_italic == other.m_italic && m_printerFont == other.m_printerFont &&
+ m_renderingMode == other.m_renderingMode;
}
AtomicString m_family;
bool m_bold;
bool m_italic;
bool m_printerFont;
+ FontRenderingMode m_renderingMode;
};
inline unsigned computeHash(const FontPlatformDataCacheKey& fontKey)
{
- unsigned hashCodes[3] = {
+ unsigned hashCodes[4] = {
CaseFoldingHash::hash(fontKey.m_family),
fontKey.m_size,
- static_cast<unsigned>(fontKey.m_bold) << 2 | static_cast<unsigned>(fontKey.m_italic) << 1 | static_cast<unsigned>(fontKey.m_printerFont)
+ static_cast<unsigned>(fontKey.m_bold) << 3 | static_cast<unsigned>(fontKey.m_italic) << 2 | static_cast<unsigned>(fontKey.m_printerFont) << 1 |
+ static_cast<unsigned>(fontKey.m_renderingMode)
};
- return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), 3 * sizeof(unsigned) / sizeof(UChar));
+ return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), 4 * sizeof(unsigned) / sizeof(UChar));
}
struct FontPlatformDataCacheKeyHash {
}
FontPlatformDataCacheKey key(familyName, fontDescription.computedPixelSize(), fontDescription.bold(), fontDescription.italic(),
- fontDescription.usePrinterFont());
+ fontDescription.usePrinterFont(), fontDescription.renderingMode());
FontPlatformData* result = 0;
bool foundResult;
FontPlatformDataCache::iterator it = gFontPlatformDataCache->find(key);
const unsigned cNormalWeight = 50;
const unsigned cBoldWeight = 63;
+// This setting is used to provide ways of switching between multiple rendering modes that may have different
+// metrics. It is used to switch between CG and GDI text on Windows.
+enum FontRenderingMode { NormalRenderingMode, AlternateRenderingMode };
+
class FontDescription {
public:
enum GenericFamilyType { NoFamily, StandardFamily, SerifFamily, SansSerifFamily,
FontDescription()
: m_specifiedSize(0), m_computedSize(0),
m_italic(false), m_smallCaps(false), m_isAbsoluteSize(false), m_weight(cNormalWeight),
- m_genericFamily(NoFamily), m_usePrinterFont(false), m_keywordSize(0)
+ m_genericFamily(NoFamily), m_usePrinterFont(false), m_renderingMode(NormalRenderingMode), m_keywordSize(0)
{}
bool operator==(const FontDescription&) const;
unsigned weight() const { return m_weight; }
GenericFamilyType genericFamily() const { return static_cast<GenericFamilyType>(m_genericFamily); }
bool usePrinterFont() const { return m_usePrinterFont; }
+ FontRenderingMode renderingMode() const { return static_cast<FontRenderingMode>(m_renderingMode); }
int keywordSize() const { return m_keywordSize; }
void setFamily(const FontFamily& family) { m_familyList = family; }
void setWeight(unsigned w) { m_weight = w; }
void setGenericFamily(GenericFamilyType genericFamily) { m_genericFamily = genericFamily; }
void setUsePrinterFont(bool p) { m_usePrinterFont = p; }
+ void setRenderingMode(FontRenderingMode mode) { m_renderingMode = mode; }
void setKeywordSize(int s) { m_keywordSize = s; }
private:
unsigned m_weight : 8;
unsigned m_genericFamily : 3; // GenericFamilyType
bool m_usePrinterFont : 1;
-
+
+ unsigned m_renderingMode : 1; // Used to switch between CG and GDI text on Windows.
+
int m_keywordSize : 4; // We cache whether or not a font is currently represented by a CSS keyword (e.g., medium). If so,
// then we can accurately translate across different generic families to adjust for different preference settings
// (e.g., 13px monospace vs. 16px everything else). Sizes are 1-8 (like the HTML size values for <font>).
&& m_weight == other.m_weight
&& m_genericFamily == other.m_genericFamily
&& m_usePrinterFont == other.m_usePrinterFont
+ && m_renderingMode == other.m_renderingMode
&& m_keywordSize == other.m_keywordSize;
}
#if PLATFORM(WIN)
GraphicsContext(HDC); // FIXME: To be removed.
- HDC getWindowsContext(bool supportAlphaBlend = false, const IntRect* = 0); // The passed in rect is used to create a bitmap for compositing inside transparency layers.
- void releaseWindowsContext(HDC, bool supportAlphaBlend = false, const IntRect* = 0); // The passed in HDC should be the one handed back by getWindowsContext.
+ HDC getWindowsContext(const IntRect&, bool supportAlphaBlend = true); // The passed in rect is used to create a bitmap for compositing inside transparency layers.
+ void releaseWindowsContext(HDC, const IntRect&, bool supportAlphaBlend = true); // The passed in HDC should be the one handed back by getWindowsContext.
#endif
#if PLATFORM(QT)
HFONT hfont = CreateFontIndirect(&winfont);
// Windows will always give us a valid pointer here, even if the face name is non-existent. We have to double-check
// and see if the family name was really used.
- HDC dc = GetDC((HWND)0);
+ HDC dc = GetDC(0);
SaveDC(dc);
SelectObject(dc, hfont);
WCHAR name[LF_FACESIZE];
FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
{
+ bool isLucidaGrande = false;
+ static AtomicString lucidaStr("Lucida Grande");
+ if (equalIgnoringCase(family, lucidaStr))
+ isLucidaGrande = true;
+
+ bool useGDI = fontDescription.renderingMode() == AlternateRenderingMode && !isLucidaGrande;
+
LOGFONT winfont;
- // The size here looks unusual. The negative number is intentional. The logical size constant is 32.
- winfont.lfHeight = -fontDescription.computedPixelSize() * 32;
+ // The size here looks unusual. The negative number is intentional. The logical size constant is 32. We do this
+ // for subpixel precision when rendering using Uniscribe. This masks rounding errors related to the HFONT metrics being
+ // different from the CGFont metrics.
+ // FIXME: We will eventually want subpixel precision for GDI mode, but the scaled rendering doesn't look as nice. That may be solvable though.
+ winfont.lfHeight = -fontDescription.computedPixelSize() * (useGDI ? 1 : 32);
winfont.lfWidth = 0;
winfont.lfEscapement = 0;
winfont.lfOrientation = 0;
winfont.lfUnderline = false;
winfont.lfStrikeOut = false;
winfont.lfCharSet = DEFAULT_CHARSET;
-#if PLATFORM(CG)
winfont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
-#else
- winfont.lfOutPrecision = OUT_TT_PRECIS;
-#endif
- winfont.lfQuality = 5; // Force cleartype.
+ winfont.lfQuality = DEFAULT_QUALITY;
winfont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
winfont.lfItalic = fontDescription.italic();
// gaps in the weight list.
// FIXME: Hardcoding Lucida Grande for now. It uses different weights than typical Win32 fonts
// (500/600 instead of 400/700).
- static AtomicString lucidaStr("Lucida Grande");
- if (equalIgnoringCase(family, lucidaStr))
+ if (isLucidaGrande) {
winfont.lfWeight = fontDescription.bold() ? 600 : 500;
- else
+ useGDI = false; // Never use GDI for Lucida Grande.
+ } else
winfont.lfWeight = fontDescription.bold() ? 700 : 400;
int len = min(family.length(), (unsigned int)LF_FACESIZE - 1);
memcpy(winfont.lfFaceName, family.characters(), len * sizeof(WORD));
HFONT hfont = CreateFontIndirect(&winfont);
// Windows will always give us a valid pointer here, even if the face name is non-existent. We have to double-check
// and see if the family name was really used.
- HDC dc = GetDC((HWND)0);
+ HDC dc = GetDC(0);
SaveDC(dc);
SelectObject(dc, hfont);
WCHAR name[LF_FACESIZE];
}
FontPlatformData* result = new FontPlatformData(hfont, fontDescription.computedPixelSize(),
- fontDescription.bold(), fontDescription.italic());
+ fontDescription.bold(), fontDescription.italic(), useGDI);
if (!result->cgFont()) {
// The creation of the CGFontRef failed for some reason. We already asserted in debug builds, but to make
// absolutely sure that we don't use this font, go ahead and return 0 so that we can fall back to the next
void FontData::platformInit()
{
m_syntheticBoldOffset = m_font.syntheticBold() ? 1.0f : 0.f;
+ m_scriptCache = 0;
+ m_scriptFontProperties = 0;
+ m_isSystemFont = false;
+
+ if (m_font.useGDI()) {
+ HDC hdc = GetDC(0);
+ HGDIOBJ oldFont = SelectObject(hdc, m_font.hfont());
+ OUTLINETEXTMETRIC metrics;
+ GetOutlineTextMetrics(hdc, sizeof(metrics), &metrics);
+ TEXTMETRIC& textMetrics = metrics.otmTextMetrics;
+ m_ascent = textMetrics.tmAscent;
+ m_descent = textMetrics.tmDescent;
+ m_lineGap = textMetrics.tmExternalLeading;
+ m_lineSpacing = m_ascent + m_descent + m_lineGap;
+ m_xHeight = m_ascent * 0.56f; // Best guess for xHeight if no x glyph is present.
+
+ GLYPHMETRICS gm;
+ MAT2 mat = { 1, 0, 0, 1 };
+ DWORD len = GetGlyphOutline(hdc, 'x', GGO_METRICS, &gm, 0, 0, &mat);
+ if (len != GDI_ERROR && gm.gmptGlyphOrigin.y > 0)
+ m_xHeight = gm.gmptGlyphOrigin.y;
+
+ m_unitsPerEm = metrics.otmEMSquare;
+
+ SelectObject(hdc, oldFont);
+ ReleaseDC(0, hdc);
+
+ return;
+ }
CGFontRef font = m_font.cgFont();
int iAscent = CGFontGetAscent(font);
float fDescent = -scaleEmToUnits(iDescent, m_unitsPerEm) * pointSize;
float fLineGap = scaleEmToUnits(iLineGap, m_unitsPerEm) * pointSize;
- m_isSystemFont = false;
if (!isCustomFont()) {
HDC dc = GetDC(0);
HGDIOBJ oldFont = SelectObject(dc, m_font.hfont());
int iXHeight = CGFontGetXHeight(font);
m_xHeight = scaleEmToUnits(iXHeight, m_unitsPerEm) * pointSize;
}
-
- m_scriptCache = 0;
- m_scriptFontProperties = 0;
}
void FontData::platformDestroy()
} else {
LOGFONT winfont;
GetObject(m_font.hfont(), sizeof(LOGFONT), &winfont);
- winfont.lfHeight = -lroundf(smallCapsHeight * 32);
+ winfont.lfHeight = -lroundf(smallCapsHeight * m_font.useGDI() ? 1 : 32);
HFONT hfont = CreateFontIndirect(&winfont);
- m_smallCapsFontData = new FontData(FontPlatformData(hfont, smallCapsHeight, fontDescription.bold(), fontDescription.italic()));
+ m_smallCapsFontData = new FontData(FontPlatformData(hfont, smallCapsHeight, fontDescription.bold(), fontDescription.italic(), m_font.useGDI()));
}
}
return m_smallCapsFontData;
if (!langFontLink)
return false;
- HDC dc = GetDC((HWND)0);
+ HDC dc = GetDC(0);
DWORD acpCodePages;
langFontLink->CodePageToCodePages(CP_ACP, &acpCodePages);
}
// TEXTMETRICS have this. Set m_treatAsFixedPitch based off that.
- HDC dc = GetDC((HWND)0);
+ HDC dc = GetDC(0);
SaveDC(dc);
SelectObject(dc, m_font.hfont());
float FontData::platformWidthForGlyph(Glyph glyph) const
{
+ if (m_font.useGDI()) {
+ HDC hdc = GetDC(0);
+ HGDIOBJ oldFont = SelectObject(hdc, m_font.hfont());
+ int width;
+ GetCharWidthI(hdc, glyph, 1, 0, &width);
+ SelectObject(hdc, oldFont);
+ ReleaseDC(0, hdc);
+ return width;
+ }
+
CGFontRef font = m_font.cgFont();
float pointSize = m_font.size();
CGSize advance;
, m_size(0)
, m_syntheticBold(false)
, m_syntheticOblique(false)
+ , m_useGDI(false)
{}
FontPlatformData()
, m_size(0)
, m_syntheticBold(false)
, m_syntheticOblique(false)
+ , m_useGDI(false)
{}
- FontPlatformData(HFONT, float size, bool bold, bool oblique);
+ FontPlatformData(HFONT, float size, bool bold, bool oblique, bool useGDI);
FontPlatformData(CGFontRef, float size, bool bold, bool oblique);
~FontPlatformData();
void setSize(float size) { m_size = size; }
bool syntheticBold() const { return m_syntheticBold; }
bool syntheticOblique() const { return m_syntheticOblique; }
+ bool useGDI() const { return m_useGDI; }
unsigned hash() const
{
bool operator==(const FontPlatformData& other) const
{
return m_font == other.m_font && m_cgFont ==other.m_cgFont && m_size == other.m_size &&
- m_syntheticBold == other.m_syntheticBold && m_syntheticOblique == other.m_syntheticOblique;
+ m_syntheticBold == other.m_syntheticBold && m_syntheticOblique == other.m_syntheticOblique &&
+ m_useGDI == other.m_useGDI;
}
private:
float m_size;
bool m_syntheticBold;
bool m_syntheticOblique;
+ bool m_useGDI;
};
}
return 1;
}
-FontPlatformData::FontPlatformData(HFONT font, float size, bool bold, bool oblique)
+FontPlatformData::FontPlatformData(HFONT font, float size, bool bold, bool oblique, bool useGDI)
: m_font(font)
, m_size(size)
, m_cgFont(0)
, m_syntheticBold(false)
, m_syntheticOblique(false)
+ , m_useGDI(useGDI)
{
HDC hdc = GetDC(0);
SaveDC(hdc);
m_syntheticOblique = true;
}
+ // For GDI text, synthetic bold and oblique never need to be set.
+ m_syntheticBold = m_syntheticOblique = false;
+
// Try the face name first. Windows may end up localizing this name, and CG doesn't know about
// the localization. If the create fails, we'll try the PostScript name.
RetainPtr<CFStringRef> fullName(AdoptCF, CFStringCreateWithCharacters(NULL, (const UniChar*)faceName, wcslen(faceName)));
, m_cgFont(font)
, m_syntheticBold(bold)
, m_syntheticOblique(oblique)
+ , m_useGDI(false)
{
}
void Font::drawGlyphs(GraphicsContext* graphicsContext, const FontData* font, const GlyphBuffer& glyphBuffer,
int from, int numGlyphs, const FloatPoint& point) const
{
+ if (font->m_font.useGDI()) {
+ // FIXME: Support alpha blending.
+ // FIXME: Support text stroke/fill.
+ // FIXME: Support text shadow.
+ Color fillColor = graphicsContext->fillColor();
+ if (fillColor.alpha() == 0)
+ return;
+
+ // We have to convert CG's two-dimensional floating point advances to just horizontal integer advances.
+ Vector<int, 2048> gdiAdvances;
+ int totalWidth = 0;
+ for (int i = 0; i < numGlyphs; i++) {
+ gdiAdvances.append(lroundf(glyphBuffer.advanceAt(from + i)));
+ totalWidth += gdiAdvances[i];
+ }
+
+ // We put slop into this rect, since glyphs can overflow the ascent/descent bounds and the left/right edges.
+ IntRect textRect(point.x() - font->lineGap(), point.y() - font->ascent() - font->lineGap(), totalWidth + 2 * font->lineGap(), font->lineSpacing());
+ HDC hdc = graphicsContext->getWindowsContext(textRect);
+ SelectObject(hdc, font->m_font.hfont());
+
+ // Set the correct color.
+ HDC textDrawingDC = hdc;
+ /*if (fillColor.hasAlpha() || graphicsContext->inTransparencyLayer()) {
+ // GDI can't handle drawing transparent text. We have to draw into a mask. We draw black text on a white-filled background.
+ // We also do this when inside transparency layers, since GDI also can't draw onto a surface with alpha.
+ graphicsContext->save();
+ graphicsContext->setFillColor(Color::white);
+ textDrawingDC = graphicsContext->getWindowsBitmapContext(textRect);
+ SetTextColor(hdc, RGB(0, 0, 0));
+ } else*/
+ SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue()));
+
+ SetBkMode(hdc, TRANSPARENT);
+ SetTextAlign(hdc, TA_LEFT | TA_BASELINE);
+
+ // Uniscribe gives us offsets to help refine the positioning of combining glyphs.
+ FloatSize translation = glyphBuffer.offsetAt(from);
+ if (translation.width() || translation.height()) {
+ XFORM xform;
+ xform.eM11 = 1.0;
+ xform.eM12 = 0;
+ xform.eM21 = 0;
+ xform.eM22 = 1.0;
+ xform.eDx = translation.width();
+ xform.eDy = translation.height();
+ ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
+ }
+ ExtTextOut(hdc, point.x(), point.y(), ETO_GLYPH_INDEX, 0, (WCHAR*)glyphBuffer.glyphs(from), numGlyphs, gdiAdvances.data());
+
+ /*if (fillColor.hasAlpha() || graphicsContext->inTransparencyLayer()) {
+ // TODOD: We have to walk the bits of the bitmap and invert them. We also copy over the green component value into the alpha value
+ // to keep ClearType looking reasonable.
+
+ // Now that we have drawn the text into a bitmap and inverted it, obtain a CGImageRef mask.
+ CGImageRef mask = graphicsContext->releaseWindowsBitmapContextIntoMask(textDrawingDC, textRect);
+
+ // Apply the mask to the fill color.
+ CGContextRef bitmapContext = graphicsContext->getWindowsCompatibleCGBitmapContext(textRect.size());
+ CGFloat red, green, blue, alpha;
+ color.getRGBA(red, green, blue, alpha);
+ CGContextSetRGBFillColor(context, red, green, blue, alpha);
+ CGContextFillRect(bitmapContext, IntRect(0, 0, textRect.width(), textRect.height()));
+ CGImageRef fillColorImage = CGBitmapContextCreateImage(bitmapContext);
+
+ // Apply the mask.
+ CGImageRef finalImage = CGImageCreateWithMask(fillColorImage, mask);
+
+ // The bitmap image needs to be drawn into the HDC.
+ graphicsContext->drawImageIntoWindowsContext(hdc, finalImage);
+
+ // Release our images and contexts.
+ CGImageRelease(mask);
+ CGImageRelease(fillColorImage);
+ CGImageRelease(finalImage);
+ CGContextRelease(bitmapContext);
+ }*/
+
+ graphicsContext->releaseWindowsContext(hdc, textRect);
+ return;
+ }
+
CGContextRef cgContext = graphicsContext->platformContext();
uint32_t oldFontSmoothingStyle = wkSetFontSmoothingStyle(cgContext);
if (context->paintingDisabled())
return;
- HDC hdc = context->getWindowsContext();
+ HDC hdc = context->getWindowsContext(r);
DrawIconEx(hdc, r.x(), r.y(), m_hIcon, r.width(), r.height(), 0, 0, DI_NORMAL);
- context->releaseWindowsContext(hdc);
+ context->releaseWindowsContext(hdc, r);
}
}
}
}
-HDC GraphicsContext::getWindowsContext(bool supportAlphaBlend, const IntRect* dstRect)
+HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend)
{
if (m_data->m_transparencyCount) {
- // We're in a transparency layer.
- ASSERT(dstRect);
- if (!dstRect)
+ if (dstRect.isEmpty())
return 0;
-
+
// Create a bitmap DC in which to draw.
BITMAPINFO bitmapInfo;
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bitmapInfo.bmiHeader.biWidth = dstRect->width();
- bitmapInfo.bmiHeader.biHeight = dstRect->height();
+ bitmapInfo.bmiHeader.biWidth = dstRect.width();
+ bitmapInfo.bmiHeader.biHeight = dstRect.height();
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = 32;
bitmapInfo.bmiHeader.biCompression = BI_RGB;
xform.eM12 = 0;
xform.eM21 = 0;
xform.eM22 = 1.0;
- xform.eDx = -dstRect->x();
- xform.eDy = -dstRect->y();
+ xform.eDx = -dstRect.x();
+ xform.eDy = -dstRect.y();
::SetWorldTransform(bitmapDC, &xform);
return bitmapDC;
return m_data->m_hdc;
}
-void GraphicsContext::releaseWindowsContext(HDC hdc, bool supportAlphaBlend, const IntRect* dstRect)
+void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend)
{
if (hdc && m_data->m_transparencyCount) {
+ if (dstRect.isEmpty())
+ return;
+
HBITMAP bitmap = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
// Need to make a CGImage out of the bitmap's pixel buffer and then draw
CGColorSpaceRelease(deviceRGB);
CGImageRef image = CGBitmapContextCreateImage(bitmapContext);
- CGContextDrawImage(m_data->m_cgContext, *dstRect, image);
+ CGContextDrawImage(m_data->m_cgContext, dstRect, image);
// Delete all our junk.
CGImageRelease(image);
roundingHackCharacters.fill(-1);
Vector<int> roundingHackWordBoundaries(glyphs.size());
roundingHackWordBoundaries.fill(-1);
- unsigned logicalSpaceWidth = fontData->m_spaceWidth * 32.0f;
+
+ const float cLogicalScale = fontData->m_font.useGDI() ? 1.0f : 32.0f;
+ unsigned logicalSpaceWidth = fontData->m_spaceWidth * cLogicalScale;
float roundedSpaceWidth = roundf(fontData->m_spaceWidth);
for (int k = 0; k < len; k++) {
for (unsigned k = 0; k < glyphs.size(); k++) {
Glyph glyph = glyphs[k];
- float advance = advances[k] / 32.0f;
- float offsetX = offsets[k].du / 32.0f;
- float offsetY = offsets[k].dv / 32.0f;
+ float advance = advances[k] / cLogicalScale;
+ float offsetX = offsets[k].du / cLogicalScale;
+ float offsetY = offsets[k].dv / cLogicalScale;
// Match AppKit's rules for the integer vs. non-integer rendering modes.
float roundedAdvance = roundf(advance);
#ifndef UniscribeController_h
#define UniscribeController_h
+#include <usp10.h>
#include "Font.h"
#include "GlyphBuffer.h"
#include "Vector.h"
-#include <usp10.h>
namespace WebCore {
if (m_isWindowed || context->paintingDisabled())
return;
- HDC hdc = context->getWindowsContext();
+ HDC hdc = context->getWindowsContext(frameGeometry());
+ // FIXME: This is completely wrong and will break in the presence of opacity, SVG transforms
+ // and CSS transforms.
// The plugin expects that the passed in DC has window coordinates.
// (This probably breaks funky SVG transform stuff)
XFORM transform;
dispatchNPEvent(npEvent);
- context->releaseWindowsContext(hdc);
+ context->releaseWindowsContext(hdc, frameGeometry());
}
void PluginViewWin::handleKeyboardEvent(KeyboardEvent* event)