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#include "config.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "WebCoreTextRenderer.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Font.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FontDescription.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "GraphicsContext.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "StringTruncator.h"
32ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "TextRun.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/unicode/Unicode.h>
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool shouldUseFontSmoothing = true;
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool isOneLeftToRightRun(const TextRun& run)
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (int i = 0; i < run.length(); i++) {
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        WTF::Unicode::Direction direction = WTF::Unicode::direction(run[i]);
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (direction == WTF::Unicode::RightToLeft || direction > WTF::Unicode::OtherNeutral)
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void doDrawTextAtPoint(GraphicsContext& context, const String& text, const IntPoint& point, const Font& font, const Color& color, int underlinedIndex)
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    TextRun run(text.characters(), text.length());
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    context.setFillColor(color, ColorSpaceDeviceRGB);
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isOneLeftToRightRun(run))
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        font.drawText(&context, run, point);
56635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    else
57635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        context.drawBidiText(font, run, point);
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (underlinedIndex >= 0) {
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(underlinedIndex < static_cast<int>(text.length()));
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int beforeWidth;
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (underlinedIndex > 0) {
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            TextRun beforeRun(text.characters(), underlinedIndex);
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            beforeWidth = font.width(beforeRun);
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            beforeWidth = 0;
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        TextRun underlinedRun(text.characters() + underlinedIndex, 1);
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int underlinedWidth = font.width(underlinedRun);
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        IntPoint underlinePoint(point);
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        underlinePoint.move(beforeWidth, 1);
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
75a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        context.setStrokeColor(color, ColorSpaceDeviceRGB);
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        context.drawLineForText(underlinePoint, underlinedWidth, false);
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebCoreDrawTextAtPoint(GraphicsContext& context, const String& text, const IntPoint& point, const Font& font, const Color& color, int underlinedIndex)
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    context.save();
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    doDrawTextAtPoint(context, text, point, font, color, underlinedIndex);
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    context.restore();
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebCoreDrawDoubledTextAtPoint(GraphicsContext& context, const String& text, const IntPoint& point, const Font& font, const Color& topColor, const Color& bottomColor, int underlinedIndex)
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    context.save();
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    IntPoint textPos = point;
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    doDrawTextAtPoint(context, text, textPos, font, bottomColor, underlinedIndex);
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    textPos.move(0, -1);
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    doDrawTextAtPoint(context, text, textPos, font, topColor, underlinedIndex);
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    context.restore();
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectfloat WebCoreTextFloatWidth(const String& text, const Font& font)
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return StringTruncator::width(text, font);
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebCoreSetShouldUseFontSmoothing(bool smooth)
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    shouldUseFontSmoothing = smooth;
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool WebCoreShouldUseFontSmoothing()
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return shouldUseFontSmoothing;
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid WebCoreSetAlwaysUsesComplexTextCodePath(bool complex)
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Font::setCodePath(complex ? Font::Complex : Font::Auto);
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool WebCoreAlwaysUsesComplexTextCodePath()
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return Font::codePath() == Font::Complex;
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
128