Fixup wrong merge: remove src/qt/src

This reapplies the patch of issue #11590 and drops the patch
from issue #11264. The former is still valid, while the latter
is hopefully resolved properly in Qt5 (see e.g. this:
https://bugs.webkit.org/show_bug.cgi?id=69419).

https://github.com/ariya/phantomjs/issues/12427
2.0
Milian Wolff 2014-08-06 15:00:34 +02:00
parent 48fabe0646
commit 514972db80
4 changed files with 2 additions and 2001 deletions

View File

@ -35,13 +35,13 @@ namespace WebCore {
// print in IE and Camino. This lets them use fewer sheets than they
// would otherwise, which is presumably why other browsers do this.
// Wide pages will be scaled down more than this.
const float printingMinimumShrinkFactor = 1.25f;
const float printingMinimumShrinkFactor = 1.;
// This number determines how small we are willing to reduce the page content
// in order to accommodate the widest line. If the page would have to be
// reduced smaller to make the widest line fit, we just clip instead (this
// behavior matches MacIE and Mozilla, at least)
const float printingMaximumShrinkFactor = 2;
const float printingMaximumShrinkFactor = 1.;
PrintContext::PrintContext(Frame* frame)
: m_frame(frame)

View File

@ -1,187 +0,0 @@
/*
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include "harfbuzz-shaper.h"
#include "harfbuzz-shaper-private.h"
#include <assert.h>
/*
// Uniscribe also defines dlig for Hebrew, but we leave this out for now, as it's mostly
// ligatures one does not want in modern Hebrew (as lam-alef ligatures).
*/
#ifndef NO_OPENTYPE
static const HB_OpenTypeFeature hebrew_features[] = {
{ HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
{0, 0}
};
#endif
/* Hebrew shaping. In the non opentype case we try to use the
presentation forms specified for Hebrew. Especially for the
ligatures with Dagesh this gives much better results than we could
achieve manually.
*/
HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item)
{
enum {
Dagesh = 0x5bc,
ShinDot = 0x5c1,
SinDot = 0x5c2,
Patah = 0x5b7,
Qamats = 0x5b8,
Holam = 0x5b9,
Rafe = 0x5bf
};
assert(shaper_item->item.script == HB_Script_Hebrew);
HB_HeuristicSetGlyphAttributes(shaper_item);
#ifndef NO_OPENTYPE
if (HB_SelectScript(shaper_item, hebrew_features)) {
const int availableGlyphs = shaper_item->num_glyphs;
if (!HB_ConvertStringToGlyphIndices(shaper_item))
return FALSE;
HB_OpenTypeShape(shaper_item, /*properties*/0);
return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE);
}
#endif
{
const HB_UChar16 *uc = shaper_item->string + shaper_item->item.pos;
unsigned short *logClusters = shaper_item->log_clusters;
HB_GlyphAttributes *attributes = shaper_item->attributes;
HB_Bool haveGlyphs;
int slen = 1;
int cluster_start = 0;
hb_uint32 i;
HB_STACKARRAY(HB_UChar16, shapedChars, 2 * shaper_item->item.length);
*shapedChars = *uc;
logClusters[0] = 0;
for (i = 1; i < shaper_item->item.length; ++i) {
hb_uint16 base = shapedChars[cluster_start];
hb_uint16 shaped = 0;
HB_Bool invalid = FALSE;
if (uc[i] == Dagesh) {
if (base >= 0x5d0
&& base <= 0x5ea
&& base != 0x5d7
&& base != 0x5dd
&& base != 0x5df
&& base != 0x5e2
&& base != 0x5e5) {
shaped = base - 0x5d0 + 0xfb30;
} else if (base == 0xfb2a || base == 0xfb2b /* Shin with Shin or Sin dot */) {
shaped = base + 2;
} else {
invalid = TRUE;
}
} else if (uc[i] == ShinDot) {
if (base == 0x05e9)
shaped = 0xfb2a;
else if (base == 0xfb49)
shaped = 0xfb2c;
else
invalid = TRUE;
} else if (uc[i] == SinDot) {
if (base == 0x05e9)
shaped = 0xfb2b;
else if (base == 0xfb49)
shaped = 0xfb2d;
else
invalid = TRUE;
} else if (uc[i] == Patah) {
if (base == 0x5d0)
shaped = 0xfb2e;
} else if (uc[i] == Qamats) {
if (base == 0x5d0)
shaped = 0xfb2f;
} else if (uc[i] == Holam) {
if (base == 0x5d5)
shaped = 0xfb4b;
} else if (uc[i] == Rafe) {
if (base == 0x5d1)
shaped = 0xfb4c;
else if (base == 0x5db)
shaped = 0xfb4d;
else if (base == 0x5e4)
shaped = 0xfb4e;
}
if (invalid) {
shapedChars[slen] = 0x25cc;
attributes[slen].clusterStart = TRUE;
attributes[slen].mark = FALSE;
attributes[slen].combiningClass = 0;
cluster_start = slen;
++slen;
}
if (shaped) {
if (shaper_item->font->klass->canRender(shaper_item->font, (HB_UChar16 *)&shaped, 1)) {
shapedChars[cluster_start] = shaped;
} else
shaped = 0;
}
if (!shaped) {
HB_CharCategory category;
int cmb;
shapedChars[slen] = uc[i];
HB_GetUnicodeCharProperties(uc[i], &category, &cmb);
if (category != HB_Mark_NonSpacing) {
attributes[slen].clusterStart = TRUE;
attributes[slen].mark = FALSE;
attributes[slen].combiningClass = 0;
attributes[slen].dontPrint = HB_IsControlChar(uc[i]);
cluster_start = slen;
} else {
attributes[slen].clusterStart = FALSE;
attributes[slen].mark = TRUE;
attributes[slen].combiningClass = cmb;
}
++slen;
}
logClusters[i] = cluster_start;
}
haveGlyphs = shaper_item->font->klass
->convertStringToGlyphIndices(shaper_item->font,
shapedChars, slen,
shaper_item->glyphs, &shaper_item->num_glyphs,
shaper_item->item.bidiLevel % 2);
HB_FREE_STACKARRAY(shapedChars);
if (!haveGlyphs)
return FALSE;
HB_HeuristicPosition(shaper_item);
}
return TRUE;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,390 +0,0 @@
/*
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
* Copyright (C) 2007 Apple Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "PrintContext.h"
#include "GraphicsContext.h"
#include "Frame.h"
#include "FrameView.h"
#include "RenderLayer.h"
#include "RenderView.h"
#include <wtf/text/StringConcatenate.h>
namespace WebCore {
// By imaging to a width a little wider than the available pixels,
// thin pages will be scaled down a little, matching the way they
// print in IE and Camino. This lets them use fewer sheets than they
// would otherwise, which is presumably why other browsers do this.
// Wide pages will be scaled down more than this.
const float printingMinimumShrinkFactor = 1;
// This number determines how small we are willing to reduce the page content
// in order to accommodate the widest line. If the page would have to be
// reduced smaller to make the widest line fit, we just clip instead (this
// behavior matches MacIE and Mozilla, at least)
const float printingMaximumShrinkFactor = 1;
PrintContext::PrintContext(Frame* frame)
: m_frame(frame)
, m_isPrinting(false)
{
}
PrintContext::~PrintContext()
{
if (m_isPrinting)
end();
}
#if COMPILER(WINSCW)
const IntRect& PrintContext::pageRect(size_t pageNumber) const
{
return m_pageRects[pageNumber];
}
#endif
void PrintContext::computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight, bool allowHorizontalTiling)
{
m_pageRects.clear();
outPageHeight = 0;
if (!m_frame->document() || !m_frame->view() || !m_frame->document()->renderer())
return;
if (userScaleFactor <= 0) {
LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor);
return;
}
RenderView* view = toRenderView(m_frame->document()->renderer());
bool isHorizontal = view->style()->isHorizontalWritingMode();
float pageWidth;
float pageHeight;
if (isHorizontal) {
pageWidth = view->docWidth();
///NOTE: if we do not reuse the previously set logical page height,
/// we can end up with off-by-one erros in the page height,
/// leading to rendering issues (e.g. rows overlap pagebreaks)
if (view->pageLogicalHeight() == 0) {
float ratio = printRect.height() / printRect.width();
pageHeight = floorf(pageWidth * ratio);
} else {
pageHeight = view->pageLogicalHeight();
}
} else {
float ratio = printRect.width() / printRect.height();
pageHeight = view->docHeight();
pageWidth = floorf(pageHeight * ratio);
}
outPageHeight = pageHeight; // this is the height of the page adjusted by margins
pageHeight -= headerHeight + footerHeight;
if (pageHeight <= 0) {
LOG_ERROR("pageHeight has bad value %.2f", pageHeight);
return;
}
computePageRectsWithPageSizeInternal(FloatSize(pageWidth / userScaleFactor, pageHeight / userScaleFactor), allowHorizontalTiling);
}
void PrintContext::computePageRectsWithPageSize(const FloatSize& pageSizeInPixels, bool allowHorizontalTiling)
{
m_pageRects.clear();
computePageRectsWithPageSizeInternal(pageSizeInPixels, allowHorizontalTiling);
}
void PrintContext::computePageRectsWithPageSizeInternal(const FloatSize& pageSizeInPixels, bool allowInlineDirectionTiling)
{
if (!m_frame->document() || !m_frame->view() || !m_frame->document()->renderer())
return;
RenderView* view = toRenderView(m_frame->document()->renderer());
IntRect docRect = view->documentRect();
int pageWidth = pageSizeInPixels.width();
int pageHeight = pageSizeInPixels.height();
bool isHorizontal = view->style()->isHorizontalWritingMode();
int docLogicalHeight = isHorizontal ? docRect.height() : docRect.width();
int pageLogicalHeight = isHorizontal ? pageHeight : pageWidth;
int pageLogicalWidth = isHorizontal ? pageWidth : pageHeight;
int inlineDirectionStart;
int inlineDirectionEnd;
int blockDirectionStart;
int blockDirectionEnd;
if (isHorizontal) {
if (view->style()->isFlippedBlocksWritingMode()) {
blockDirectionStart = docRect.maxY();
blockDirectionEnd = docRect.y();
} else {
blockDirectionStart = docRect.y();
blockDirectionEnd = docRect.maxY();
}
inlineDirectionStart = view->style()->isLeftToRightDirection() ? docRect.x() : docRect.maxX();
inlineDirectionEnd = view->style()->isLeftToRightDirection() ? docRect.maxX() : docRect.x();
} else {
if (view->style()->isFlippedBlocksWritingMode()) {
blockDirectionStart = docRect.maxX();
blockDirectionEnd = docRect.x();
} else {
blockDirectionStart = docRect.x();
blockDirectionEnd = docRect.maxX();
}
inlineDirectionStart = view->style()->isLeftToRightDirection() ? docRect.y() : docRect.maxY();
inlineDirectionEnd = view->style()->isLeftToRightDirection() ? docRect.maxY() : docRect.y();
}
unsigned pageCount = ceilf((float)docLogicalHeight / pageLogicalHeight);
for (unsigned i = 0; i < pageCount; ++i) {
int pageLogicalTop = blockDirectionEnd > blockDirectionStart ?
blockDirectionStart + i * pageLogicalHeight :
blockDirectionStart - (i + 1) * pageLogicalHeight;
if (allowInlineDirectionTiling) {
for (int currentInlinePosition = inlineDirectionStart;
inlineDirectionEnd > inlineDirectionStart ? currentInlinePosition < inlineDirectionEnd : currentInlinePosition > inlineDirectionEnd;
currentInlinePosition += (inlineDirectionEnd > inlineDirectionStart ? pageLogicalWidth : -pageLogicalWidth)) {
int pageLogicalLeft = inlineDirectionEnd > inlineDirectionStart ? currentInlinePosition : currentInlinePosition - pageLogicalWidth;
IntRect pageRect(pageLogicalLeft, pageLogicalTop, pageLogicalWidth, pageLogicalHeight);
if (!isHorizontal)
pageRect = pageRect.transposedRect();
m_pageRects.append(pageRect);
}
} else {
int pageLogicalLeft = inlineDirectionEnd > inlineDirectionStart ? inlineDirectionStart : inlineDirectionStart - pageLogicalWidth;
IntRect pageRect(pageLogicalLeft, pageLogicalTop, pageLogicalWidth, pageLogicalHeight);
if (!isHorizontal)
pageRect = pageRect.transposedRect();
m_pageRects.append(pageRect);
}
}
}
void PrintContext::begin(float width, float height)
{
// This function can be called multiple times to adjust printing parameters without going back to screen mode.
m_isPrinting = true;
float minLayoutWidth = width * printingMinimumShrinkFactor;
float minLayoutHeight = height * printingMinimumShrinkFactor;
// This changes layout, so callers need to make sure that they don't paint to screen while in printing mode.
m_frame->setPrinting(true, FloatSize(minLayoutWidth, minLayoutHeight), printingMaximumShrinkFactor / printingMinimumShrinkFactor, Frame::AdjustViewSize);
}
float PrintContext::computeAutomaticScaleFactor(const FloatSize& availablePaperSize)
{
if (!m_frame->view())
return 1;
bool useViewWidth = true;
if (m_frame->document() && m_frame->document()->renderView())
useViewWidth = m_frame->document()->renderView()->style()->isHorizontalWritingMode();
float viewLogicalWidth = useViewWidth ? m_frame->view()->contentsWidth() : m_frame->view()->contentsHeight();
if (viewLogicalWidth < 1)
return 1;
float maxShrinkToFitScaleFactor = 1 / printingMaximumShrinkFactor;
float shrinkToFitScaleFactor = (useViewWidth ? availablePaperSize.width() : availablePaperSize.height()) / viewLogicalWidth;
return max(maxShrinkToFitScaleFactor, shrinkToFitScaleFactor);
}
void PrintContext::spoolPage(GraphicsContext& ctx, int pageNumber, float width)
{
// FIXME: Not correct for vertical text.
IntRect pageRect = m_pageRects[pageNumber];
float scale = width / pageRect.width();
ctx.save();
ctx.scale(FloatSize(scale, scale));
ctx.translate(-pageRect.x(), -pageRect.y());
ctx.clip(pageRect);
m_frame->view()->paintContents(&ctx, pageRect);
ctx.restore();
}
void PrintContext::spoolRect(GraphicsContext& ctx, const IntRect& rect)
{
// FIXME: Not correct for vertical text.
ctx.save();
ctx.translate(-rect.x(), -rect.y());
ctx.clip(rect);
m_frame->view()->paintContents(&ctx, rect);
ctx.restore();
}
void PrintContext::end()
{
ASSERT(m_isPrinting);
m_isPrinting = false;
m_frame->setPrinting(false, FloatSize(), 0, Frame::AdjustViewSize);
}
static RenderBoxModelObject* enclosingBoxModelObject(RenderObject* object)
{
while (object && !object->isBoxModelObject())
object = object->parent();
if (!object)
return 0;
return toRenderBoxModelObject(object);
}
int PrintContext::pageNumberForElement(Element* element, const FloatSize& pageSizeInPixels)
{
// Make sure the element is not freed during the layout.
RefPtr<Element> elementRef(element);
element->document()->updateLayout();
RenderBoxModelObject* box = enclosingBoxModelObject(element->renderer());
if (!box)
return -1;
Frame* frame = element->document()->frame();
FloatRect pageRect(FloatPoint(0, 0), pageSizeInPixels);
PrintContext printContext(frame);
printContext.begin(pageRect.width(), pageRect.height());
FloatSize scaledPageSize = pageSizeInPixels;
scaledPageSize.scale(frame->view()->contentsSize().width() / pageRect.width());
printContext.computePageRectsWithPageSize(scaledPageSize, false);
int top = box->offsetTop();
int left = box->offsetLeft();
size_t pageNumber = 0;
for (; pageNumber < printContext.pageCount(); pageNumber++) {
const IntRect& page = printContext.pageRect(pageNumber);
if (page.x() <= left && left < page.maxX() && page.y() <= top && top < page.maxY())
return pageNumber;
}
return -1;
}
String PrintContext::pageProperty(Frame* frame, const char* propertyName, int pageNumber)
{
Document* document = frame->document();
PrintContext printContext(frame);
printContext.begin(800); // Any width is OK here.
document->updateLayout();
RefPtr<RenderStyle> style = document->styleForPage(pageNumber);
// Implement formatters for properties we care about.
if (!strcmp(propertyName, "margin-left")) {
if (style->marginLeft().isAuto())
return String("auto");
return String::number(style->marginLeft().value());
}
if (!strcmp(propertyName, "line-height"))
return String::number(style->lineHeight().value());
if (!strcmp(propertyName, "font-size"))
return String::number(style->fontDescription().computedPixelSize());
if (!strcmp(propertyName, "font-family"))
return style->fontDescription().family().family().string();
if (!strcmp(propertyName, "size"))
return makeString(String::number(style->pageSize().width().value()), ' ', String::number(style->pageSize().height().value()));
return makeString("pageProperty() unimplemented for: ", propertyName);
}
bool PrintContext::isPageBoxVisible(Frame* frame, int pageNumber)
{
return frame->document()->isPageBoxVisible(pageNumber);
}
String PrintContext::pageSizeAndMarginsInPixels(Frame* frame, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft)
{
IntSize pageSize(width, height);
frame->document()->pageSizeAndMarginsInPixels(pageNumber, pageSize, marginTop, marginRight, marginBottom, marginLeft);
// We don't have a makeString() function that takes up to 12 arguments, if this is a hot function, we can provide one.
return makeString('(', String::number(pageSize.width()), ", ", String::number(pageSize.height()), ") ") +
makeString(String::number(marginTop), ' ', String::number(marginRight), ' ', String::number(marginBottom), ' ', String::number(marginLeft));
}
int PrintContext::numberOfPages(Frame* frame, const FloatSize& pageSizeInPixels)
{
frame->document()->updateLayout();
FloatRect pageRect(FloatPoint(0, 0), pageSizeInPixels);
PrintContext printContext(frame);
printContext.begin(pageRect.width(), pageRect.height());
// Account for shrink-to-fit.
FloatSize scaledPageSize = pageSizeInPixels;
scaledPageSize.scale(frame->view()->contentsSize().width() / pageRect.width());
printContext.computePageRectsWithPageSize(scaledPageSize, false);
return printContext.pageCount();
}
void PrintContext::spoolAllPagesWithBoundaries(Frame* frame, GraphicsContext& graphicsContext, const FloatSize& pageSizeInPixels)
{
if (!frame->document() || !frame->view() || !frame->document()->renderer())
return;
frame->document()->updateLayout();
PrintContext printContext(frame);
printContext.begin(pageSizeInPixels.width(), pageSizeInPixels.height());
float pageHeight;
printContext.computePageRects(FloatRect(FloatPoint(0, 0), pageSizeInPixels), 0, 0, 1, pageHeight);
const float pageWidth = pageSizeInPixels.width();
const Vector<IntRect>& pageRects = printContext.pageRects();
int totalHeight = pageRects.size() * (pageSizeInPixels.height() + 1) - 1;
// Fill the whole background by white.
graphicsContext.setFillColor(Color(255, 255, 255), ColorSpaceDeviceRGB);
graphicsContext.fillRect(FloatRect(0, 0, pageWidth, totalHeight));
graphicsContext.save();
graphicsContext.translate(0, totalHeight);
graphicsContext.scale(FloatSize(1, -1));
int currentHeight = 0;
for (size_t pageIndex = 0; pageIndex < pageRects.size(); pageIndex++) {
// Draw a line for a page boundary if this isn't the first page.
if (pageIndex > 0) {
graphicsContext.save();
graphicsContext.setStrokeColor(Color(0, 0, 255), ColorSpaceDeviceRGB);
graphicsContext.setFillColor(Color(0, 0, 255), ColorSpaceDeviceRGB);
graphicsContext.drawLine(IntPoint(0, currentHeight),
IntPoint(pageWidth, currentHeight));
graphicsContext.restore();
}
graphicsContext.save();
graphicsContext.translate(0, currentHeight);
printContext.spoolPage(graphicsContext, pageIndex, pageWidth);
graphicsContext.restore();
currentHeight += pageSizeInPixels.height() + 1;
}
graphicsContext.restore();
}
}