📄 kwqpainter.cpp
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- *//* * Copyright (C) 2001, 2002 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include <gdk/gdk.h>#include "KWQPainter.h"#include "KWQAssertions.h"#include "KWQFontMetrics.h"//#include "KWQKHTMLPart.h"#include "KWQPaintDevice.h"#include "KWQPixmap.h"#include "KWQPointArray.h"#include "KWQPrinter.h"#include "KWQWidget.h"#include "KWQPtrStack.h"#include "WebCoreTextRendererFactory.h"#include "WebCoreTextRenderer.h"#include "WebCoreImageRenderer.h"#include "KWIQCGContext.h"#include "KWQFoundationExtras.h"#include "KWQLogging.h"/* *FIXME: will crash for example in resizing frames, because drawing context is not set. * Apple has global context, and they construct painter with statement like "QPainter painter;" * for example see render_frames.cpp:440 * */static inlinevoid initGdkRectangle(GdkRectangle* rect, int x, int y, int w, int h){ rect->x=x; rect->y=y; rect->width=w; rect->height=h;}struct QPState { QPState() : paintingDisabled(false),clip(0) { } QFont font; QPen pen; QBrush brush; bool paintingDisabled; GdkRegion* clip;};struct QPainterPrivate { QPainterPrivate() : textRenderer(0), focusRingPath(0), focusRingWidth(0), focusRingOffset(0), hasFocusRingColor(false), context(0) { } ~QPainterPrivate() { KWQRelease(textRenderer); delete focusRingPath; } QPState state; QPtrStack<QPState> stack; WebCoreTextRenderer* textRenderer; QFont textRendererFont; QRect *focusRingPath; int focusRingWidth; int focusRingOffset; bool hasFocusRingColor; QColor focusRingColor; CGContextRef context;};QPainter::QPainter() : data(new QPainterPrivate), _isForPrinting(false), _usesInactiveTextBackgroundColor(false), _drawsFocusRing(true){}QPainter::QPainter(bool forPrinting) : data(new QPainterPrivate), _isForPrinting(forPrinting), _usesInactiveTextBackgroundColor(false), _drawsFocusRing(true){}QPainter::~QPainter(){ delete data;}QPaintDevice *QPainter::device() const{ static QPrinter printer; static QPaintDevice screen; return _isForPrinting ? &printer : &screen;}const QFont &QPainter::font() const{ return data->state.font;}void QPainter::setFont(const QFont &aFont){ data->state.font = aFont;}QFontMetrics QPainter::fontMetrics() const{ return data->state.font;}const QPen &QPainter::pen() const{ return data->state.pen;}void QPainter::setPen(const QPen &pen){ data->state.pen = pen;}void QPainter::setPen(PenStyle style){ data->state.pen.setStyle(style); data->state.pen.setColor(Qt::black); data->state.pen.setWidth(0);}void QPainter::setPen(QRgb rgb){ data->state.pen.setStyle(SolidLine); data->state.pen.setColor(rgb); data->state.pen.setWidth(0);}void QPainter::setBrush(const QBrush &brush){ data->state.brush = brush;}void QPainter::setBrush(BrushStyle style){ data->state.brush.setStyle(style); data->state.brush.setColor(Qt::black);}void QPainter::setBrush(QRgb rgb){ data->state.brush.setStyle(SolidPattern); data->state.brush.setColor(rgb);}const QBrush &QPainter::brush() const{ return data->state.brush;}QRect QPainter::xForm(const QRect &aRect) const{ // No difference between device and model coords, so the identity transform is ok. return aRect;}void QPainter::save(){ data->stack.push(new QPState(data->state)); data->context->saveGraphicsState(); }void QPainter::restore(){ if (data->stack.isEmpty()) { ERROR("ERROR void QPainter::restore() stack is empty"); return; } QPState *ps = data->stack.pop(); data->state = *ps; delete ps; data->context->restoreGraphicsState();}// Draws a filled rectangle with a stroked border.void QPainter::drawRect(int x, int y, int w, int h){ if (data->state.paintingDisabled) return; if (data->state.brush.style() != NoBrush) { _setColorFromBrush(); gdk_draw_rectangle(data->context->drawable, data->context->gc, TRUE, x, y, w, h); } if (data->state.pen.style() != NoPen) { _setColorFromPen(); gdk_draw_rectangle(data->context->drawable, data->context->gc, FALSE, x, y, w-1, h-1); }}void QPainter::_setColorFromBrush(){ ASSERT(data->state.brush.color().isValid()); GdkColor color; QColor qc = data->state.brush.color(); color.red = qc.red() *255; color.green = qc.green() * 255; color.blue = qc.blue() * 255; gdk_gc_set_rgb_fg_color(data->context->gc, &color); gdk_gc_set_fill (data->context->gc, GDK_SOLID);}void QPainter::_setColorFromPen(){ ASSERT(data->state.pen.color().isValid()); GdkColor color; QColor qc = data->state.pen.color(); color.red = qc.red() *255; color.green = qc.green() * 255; color.blue = qc.blue() * 255; //color.pixel = qc.rgb() & 0x00FFFFFF; gdk_gc_set_rgb_fg_color(data->context->gc, &color);}// This is only used to draw borders.// This is also used to draw lines under textvoid QPainter::drawLine(int x1, int y1, int x2, int y2){ if (data->state.paintingDisabled) return; PenStyle penStyle = data->state.pen.style(); if (penStyle == NoPen) return; _setColorFromPen(); gdk_gc_set_line_attributes (data->context->gc, data->state.pen.width(), GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER); gdk_draw_line(data->context->drawable, data->context->gc, x1, y1, x2, y2);}// This method is only used to draw the little circles used in lists.void QPainter::drawEllipse(int x, int y, int w, int h){ if (data->state.paintingDisabled) return; if (data->state.brush.style() != NoBrush) { _setColorFromBrush(); gdk_draw_arc(data->context->drawable, data->context->gc, TRUE, x, y, w, h, 0, 360*64); } if (data->state.pen.style() != NoPen) { _setColorFromPen(); gdk_draw_arc(data->context->drawable, data->context->gc, FALSE, x, y, w, h, 0, 360*64); }}void QPainter::drawArc (int x, int y, int w, int h, int a, int alen){ // Only supports arc on circles. That's all khtml needs. if (data->state.paintingDisabled) return; if (data->state.pen.style() != NoPen) { _setColorFromPen(); gdk_draw_arc(data->context->drawable, data->context->gc, FALSE, x, y, w, h, (gint)((a*16)/64), (gint) ((alen*16)/64)); }}void QPainter::drawLineSegments(const QPointArray &points, int index, int nlines){ if (data->state.paintingDisabled) return; _drawPoints (points, 0, index, nlines, false);}void QPainter::drawPolyline(const QPointArray &points, int index, int npoints){ _drawPoints (points, 0, index, npoints, false);}void QPainter::drawPolygon(const QPointArray &points, bool winding, int index, int npoints){ _drawPoints (points, winding, index, npoints, true);}void QPainter::drawConvexPolygon(const QPointArray &points){ _drawPoints (points, false, 0, -1, true);}void QPainter::_drawPoints (const QPointArray &_points, bool winding, int index, int _npoints, bool fill){ if (data->state.paintingDisabled) return; int npoints = _npoints != -1 ? _npoints : _points.size()-index; GdkPoint points[npoints]; for (int i = 0; i < npoints; i++) { points[i].x = _points[index+i].x(); points[i].y = _points[index+i].y(); } if (fill && data->state.brush.style() != NoBrush) { _setColorFromBrush(); } if (data->state.pen.style() != NoPen) { _setColorFromPen(); } gdk_draw_polygon(data->context->drawable, data->context->gc, fill, points, npoints);}void QPainter::drawPixmap(const QPoint &p, const QPixmap &pix){ drawPixmap(p.x(), p.y(), pix);}void QPainter::drawPixmap(const QPoint &p, const QPixmap &pix, const QRect &r){ drawPixmap(p.x(), p.y(), pix, r.x(), r.y(), r.width(), r.height());}struct CompositeOperator{ const char *name; NSCompositingOperation value;};#define NUM_COMPOSITE_OPERATORS 14struct CompositeOperator compositeOperators[NUM_COMPOSITE_OPERATORS] = { { "clear", NSCompositeClear }, { "copy", NSCompositeCopy }, { "source-over", NSCompositeSourceOver }, { "source-in", NSCompositeSourceIn }, { "source-out", NSCompositeSourceOut }, { "source-atop", NSCompositeSourceAtop }, { "destination-over", NSCompositeDestinationOver }, { "destination-in", NSCompositeDestinationIn }, { "destination-out", NSCompositeDestinationOut }, { "destination-atop", NSCompositeDestinationAtop }, { "xor", NSCompositeXOR }, { "darker", NSCompositePlusDarker }, { "highlight", NSCompositeHighlight }, { "lighter", NSCompositePlusLighter }};int QPainter::getCompositeOperation(CGContextRef context){ return (int) WebCoreImageRendererFactory::sharedFactory()->CGCompositeOperationInContext(context);}void QPainter::setCompositeOperation (CGContextRef context, QString op){ WebCoreImageRendererFactory::sharedFactory()->setCGCompositeOperationFromString(context, op.latin1());}void QPainter::setCompositeOperation (CGContextRef context, int op){ WebCoreImageRendererFactory::sharedFactory()->setCGCompositeOperation(context, op);}int QPainter::compositeOperatorFromString (QString aString){ NSCompositingOperation op = NSCompositeSourceOver; if (aString.length()) { const char *operatorString = aString.ascii(); int i; for (i = 0; i < NUM_COMPOSITE_OPERATORS; i++) { if (strcasecmp (operatorString, compositeOperators[i].name) == 0) { return compositeOperators[i].value; } } } return (int)op;}void QPainter::drawPixmap(const QPoint &p, const QPixmap &pix, const QRect &r, const QString &compositeOperator){ drawPixmap(p.x(), p.y(), pix, r.x(), r.y(), r.width(), r.height(), compositeOperatorFromString(compositeOperator));}void QPainter::drawPixmap( int x, int y, const QPixmap &pixmap, int sx, int sy, int sw, int sh, int compositeOperator, CGContextRef context)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -