18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Apple Inc.  All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebKitGraphics.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebKit.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebKitDLL.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebPreferences.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebCore/Font.h>
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebCore/FontDescription.h>
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebCore/FontSelector.h>
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebCore/GraphicsContext.h>
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebCore/PlatformString.h>
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebCore/StringTruncator.h>
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebCore/WebCoreTextRenderer.h>
412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <wtf/unicode/CharacterNames.h>
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <CoreGraphics/CoreGraphics.h>
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <WebKitSystemInterface/WebKitSystemInterface.h>
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WebCore;
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic Font makeFont(const WebFontDescription& description)
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    AtomicString::init();
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String fontFamilyString(description.family, description.familyLength);
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FontDescription f;
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FontFamily family;
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    family.setFamily(fontFamilyString);
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    f.setFamily(family);
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    f.setSpecifiedSize(description.size);
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    f.setComputedSize(description.size);
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    f.setItalic(description.italic);
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    f.setWeight(description.bold ? FontWeightBold : FontWeightNormal);
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    f.setIsAbsoluteSize(true);
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FontSmoothingType smoothingType;
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (SUCCEEDED(WebPreferences::sharedStandardPreferences()->fontSmoothing(&smoothingType)))
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        f.setRenderingMode(smoothingType == FontSmoothingTypeWindows ? AlternateRenderingMode : NormalRenderingMode);
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Font font(f, 0, 0);
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    font.update(0);
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return font;
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Text shadow is added post 3.1.1.  In order for nightlies to not break Safari 3.1.1, we should still allow
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// the old WebTextRenderInfo that has a smaller structSize than the current one with the new text shadow data members.
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstruct WebTextRenderInfoWithoutShadow
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    DWORD structSize;
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGContextRef cgContext;
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    LPCTSTR text;
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int length;
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    POINT pt;
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    const WebFontDescription* description;
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CGColorRef color;
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int underlinedIndex;
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool drawAsPassword;
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int overrideSmoothingLevel; // pass in -1 if caller does not want to override smoothing level
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebDrawText(WebTextRenderInfo* info)
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!info || info->structSize < sizeof(WebTextRenderInfoWithoutShadow) || !info->cgContext || !info->description)
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int oldFontSmoothingLevel = -1;
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (info->overrideSmoothingLevel >= 0) {
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        oldFontSmoothingLevel = wkGetFontSmoothingLevel();
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        wkSetFontSmoothingLevel(info->overrideSmoothingLevel);
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        GraphicsContext context(info->cgContext);
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String drawString(info->text, info->length);
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (info->drawAsPassword)
1062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            drawString = drawString.impl()->secure(WTF::Unicode::bullet);
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        context.save();
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Set shadow setting
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (info->structSize == sizeof(WebTextRenderInfo) &&
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            (info->shadowOffset.cx || info->shadowOffset.cy || info->shadowBlur || info->shadowColor))
113a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            context.setShadow(FloatSize(info->shadowOffset.cx, info->shadowOffset.cy), info->shadowBlur, info->shadowColor, ColorSpaceDeviceRGB);
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        WebCoreDrawTextAtPoint(context, drawString, info->pt, makeFont(*(info->description)), info->color, info->underlinedIndex);
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        context.restore();
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (info->overrideSmoothingLevel >= 0)
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        wkSetFontSmoothingLevel(oldFontSmoothingLevel);
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectfloat TextFloatWidth(LPCTSTR text, int length, const WebFontDescription& description)
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return WebCoreTextFloatWidth(String(text, length), makeFont(description));
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FontMetrics(const WebFontDescription& description, int* ascent, int* descent, int* lineSpacing)
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!ascent && !descent && !lineSpacing)
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Font font(makeFont(description));
1342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    const WebCore::FontMetrics& fontMetrics(font.fontMetrics());
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (ascent)
1372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        *ascent = fontMetrics.ascent();
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (descent)
1402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        *descent = fontMetrics.descent();
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (lineSpacing)
1432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        *lineSpacing = fontMetrics.lineSpacing();
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunsigned CenterTruncateStringToWidth(LPCTSTR text, int length, const WebFontDescription& description, float width, WCHAR* buffer)
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(buffer);
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    String result = StringTruncator::centerTruncate(String(text, length), width, makeFont(description));
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    memcpy(buffer, result.characters(), result.length() * sizeof(UChar));
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    buffer[result.length()] = '\0';
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result.length();
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunsigned RightTruncateStringToWidth(LPCTSTR text, int length, const WebFontDescription& description, float width, WCHAR* buffer)
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(buffer);
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    String result = StringTruncator::rightTruncate(String(text, length), width, makeFont(description));
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    memcpy(buffer, result.characters(), result.length() * sizeof(UChar));
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    buffer[result.length()] = '\0';
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result.length();
1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebKitSetShouldUseFontSmoothing(bool smooth)
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    WebCoreSetShouldUseFontSmoothing(smooth);
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool WebKitShouldUseFontSmoothing()
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return WebCoreShouldUseFontSmoothing();
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
175