发展历史呢谈WebKit、Gecko使用图形库

啊谈WebKit、Gecko使用图形库

读书了Graphics in
Google
Chrome之后,觉得作为浏览器内核WebKit、Gecko,为了能够快美观的显得页面的始末,选择适合的图形库非常主要。如果图形库选择不当,往往会促成页面及出示的字、图片未漂亮,看起到底让丁觉得别别扭扭,更为糟糕的凡排布局出现乱,简直无法阅览。

打浏览器发展之史来拘禁,IE系列浏览器的网页布局、文字图片展示的姣好程度还是一对一高的,也许这跟Microsoft图形显示上面的造诣相关,到目前为止linux桌面显示还是与民俗的windows桌面显示出一定之距离。


比较Firefox1.5,Firefox3.0图形显示上面呢生相当可怜之腾飞,这应当归功给完全采用Cario图形库来展示页面,目前应完全达到了
IE6的显示力量。可见图片显示的好和那个,直接控制了一致暂缓浏览器的成色以及用户接受程度。那到底什么是图形库?其重要性意义是什么?目前WebKit、
Gecko可使用什么图形库?它们以浏览器被凡何许发挥其应之意向吗?

同等、图形库概述及其关键职能

A graphics library is
a program designed to aid in rendering computer graphics to a monitor.
This typically involves providing optimized versions of functions that
handle common rendering tasks.

This can be done
purely in software and running on the CPU, common in embedded systems,
or being hardware accelerated by a GPU, more common in PCs. By employing
these functions, a program can assemble an image to be output to a
monitor. This relieves the programmer of the task of creating and
optimizing these functions, and allows them to focus on building the
graphics program.

目前关键的图形库有:

windows提供的GDI/GDI+、DirectX、OpenGL;

支持X的有Cario、GTK、QT、OpenGL;

另外的还有Skia(google提供)、Quartz
2D(apple提供)、wxWidget等;


般说来图形库只提供绘画图形,渲染文字、图片等,不管是2D还是3D,其勤不提供信息处理,简单的说来就是什么样高效的在一齐指定的画布上以线、文字、
图片显示出,其中高频涉及字体、颜色相当;典型的图纸库如GDI/GDI+、Cario、DirectX、Quartz
2D等于;

如果按钮、菜单、窗口等图形组件往往是冲图形库的底蕴及描绘出来的连发出相对固化形状,同时一般装有信息处理效果;相关兑现有GTK、QT、wxWidget、windows组件等;

里面GTK、QT、wxWidget、Skia等不但提供图片组件,同时提供图形库的功能;而Cario则是一个纯的图形库,类似与Quartz
2D,目前GTK2尽管一心依据Cario来实现;

出于
于浏览器页面元素的多少在不确定性,将页面及之片段因素对许成为图组件可能引致一个页面使用组件过多之题目(早期的IE就已经出现用GDI对象了多的现
象)。因此尽可能的将一个页面的有所因素显示在一个图形组件上,至于该出示交给图形库来拍卖,其消息应交互交给DOM及原生窗口消息循环来就。

自这边我们可以更的确认图形库在浏览器中之基本点,以及随着用户需要的长与硬件的晋级,浏览器被应用3D效果应是一个死的可行性。

次、Gecko中运用图形库Cario

1、Cario概述

Cairo is a 2D graphics
library with support for multiple output devices. Currently supported
output targets include the X Window System, Quartz, Win32, image
buffers, PostScript, PDF, and SVG file output. Experimental backends
include OpenGL (through glitz), XCB, BeOS, OS/2, and DirectFB.

Cairo is designed to
produce consistent output on all output media while taking advantage of
display hardware acceleration when available (eg. through the X Render
Extension).

其重大优点在于那当X、Win32、Quartz的基本功及合了图形库的操作方法,同时支持PS、PDF、SVG、PNG/JPEG等图像格式的出口,极大的好页面的双重以,在glitz的支撑下支持部分3D职能。

2、Cario在Gecko中的使用

先是提供一个gfxASurface抽象类,代表一样片好画的画布;提供一个gfxContext类,它用来治本究竟怎样作画,如绘画圆形、旋转,维护画布的状态、当前颜色、路径等,其勤得一个gfxASurface子类实例来初始化;

其次不同的图样输出实现不同之gfxASurface子类设gfxWindowsSurface、gfxXlibSurface、gfxQuartzSurface、gfxGlitzSurface、gfxQuartzPDFSurface、gfxPSSurface等;

下提供一个DeviceContextImpl类实现nsIDeviceContext接口,以叙指定原生Widget相关的书属性与创造好在该原生Widget上写的nsIRenderingContext接口实现;

假如nsThebesRenderingContext类实现了nsIRenderingContext接口,以供应外部(如不同之DOM
Node页面元素对应的不等Frame)在该及显示文字、图像、作图形等;

下一场当解析、布局了DOM页面元素后需要打起不同的页面元素时虽由DeviceContextImpl类实例来创造nsThebesRenderingContext类实现,并初始化它,其初始化代码如下:

nsThebesRenderingContext::Init(nsIDeviceContext*
aContext, nsIWidget *aWidget)

{

nsThebesDeviceContext
*thebesDC =
static_castnsIRenderingContext接口究竟生怎么样重大方法?

// RenderingContext
interface

class
nsIRenderingContext : public nsISupports

{

public:

……………………………………………………………….

/**

* Initialize the
RenderingContext

* @param aContext the
device context to use.

* @param aWidget the
widget to hook up to

* @result The result
of the initialization, NS_Ok if no errors

*/

NS_IMETHOD
Init(nsIDeviceContext* aContext, nsIWidget *aWidget) = 0;

/**

* Get the
DeviceContext that this RenderingContext was initialized

* with. This function
addrefs the device context. Though it might

* be better if it
just returned it directly, without addrefing.

* @result the device
context

*/

NS_IMETHOD
GetDeviceContext(nsIDeviceContext *& aDeviceContext) = 0;

/**

* Sets the forground
color for the RenderingContext

* @param aColor The
color to set the RenderingContext to

*/

NS_IMETHOD
SetColor(nscolor aColor) = 0;

/**

* Get the forground
color for the RenderingContext

* @return The current
forground color of the RenderingContext

*/

NS_IMETHOD
GetColor(nscolor &aColor) const = 0;

/**

* Sets the font for
the RenderingContext

* @param aFont The
font to use in the RenderingContext

*/

NS_IMETHOD
SetFont(const nsFont& aFont, nsIAtom* aLangGroup) = 0;

/**

* Sets the font for
the RenderingContext

* @param aFontMetric
The font metrics representing the

* font to use in the
RenderingContext

*/

NS_IMETHOD
SetFont(nsIFontMetrics *aFontMetrics) = 0;

/**

* Get the current
fontmetrics for the RenderingContext

* @return The current
font of the RenderingContext

*/

NS_IMETHOD
GetFontMetrics(nsIFontMetrics *&aFontMetrics) = 0;

/**

* Add in a translate
to the RenderingContext’s transformation matrix

* @param aX The
horizontal translation

* @param aY The
vertical translation

*/

NS_IMETHOD
Translate(nscoord aX, nscoord aY) = 0;

/**

* Add in a scale to
the RenderingContext’s transformation matrix

* @param aX The
horizontal scale

* @param aY The
vertical scale

*/

NS_IMETHOD
Scale(float aSx, float aSy) = 0;

/**

* Draw a line

* @param aXO starting
horiztonal coord in twips

* @param aY0 starting
vertical coord in twips

* @param aX1 end
horiztonal coord in twips

* @param aY1 end
vertical coord in twips

*/

NS_IMETHOD
DrawLine(nscoord aX0, nscoord aY0, nscoord aX1, nscoord aY1) = 0;

/**

* Draw a
rectangle

* @param aRect The
rectangle to draw

*/

NS_IMETHOD
DrawRect(const nsRect& aRect) = 0;

/**

* Draw a string in
the RenderingContext

* @param aString The
string to draw

* @param aLength The
length of the aString

* @param aX
Horizontal starting point of baseline

* @param aY Vertical
starting point of baseline.

* @param aSpacing
inter-character spacing to apply

*/

NS_IMETHOD
DrawString(const char *aString, PRUint32 aLength,

nscoord aX, nscoord
aY,

const nscoord*
aSpacing = nsnull) = 0;

/*

* Tiles an image over
an area

* @param aImage Image
to tile

* @param aXImageStart
x location where the origin (0,0) of the image starts

* @param aYImageStart
y location where the origin (0,0) of the image starts

* @param aTargetRect
area to draw to

* @param
aSubimageRect the subimage (in tile space) which we expect to

* sample from; may be
null to indicate that the whole image is

* OK to sample
from

*/

NS_IMETHOD
DrawTile(imgIContainer *aImage,

nscoord aXImageStart,
nscoord aYImageStart,

const nsRect *
aTargetRect,

const nsIntRect *
aSubimageRect) = 0;

…………………………………………………………………….

};

里头DrawString、DrawTile方法极其常用,其分别针对许怎样展示文字与图像。

本着图形库显示文字的基本原理可以参见Font
technology and Freetype及FreeType Glyph Conventions。

至于图形库如何展示不同格式的图像而参照如gif、jpeg、png等。

Gecko对Cario的应用还反映在针对canvas标签的落实,具体可参照nsCanvasRenderingContext2D.cpp、nsHTMLCanvasElement.cpp等。

其三、WebKit中使用图形库

1、WebKit支持之图形库


前WebKit支持的图形库包括Cairo、Gtk、Qt、Wx、Cg、Mac、Skia等,虽然不同之图纸库能支持不同的阳台,但那于不同平台达成的显示
效果啊不尽相同。至于以一个点名的阳台及到底以何种库,则显得有老要命的灵活性。就现阶段来拘禁,在windows平台上可选的图形库有Cairo、Qt、
Wx、Cg、Skia等,其中Graphics in Google
Chrome阐述了Chrome关于图形库的选料。

骨子里打WebKit的角度来拘禁,它通过提供平等组与Gecko中nsIRenderingContext类似的官图形接口,而各异之图形库则根据自己的两样实现了这些公共图形接口,以提供被WebCore元素使用,从而得以于WebKit支持不同之图形库。

2、WebKit支持不同图形库的贯彻

以WebKit中提供了一个GraphicsContext类,其中囊括有的图形接口,完全类似nsIRenderingContext,针对不同平台的特征,其定义着寓部分异平台特有的

宏及元素定义。


目录webcore\platform\graphics\下的子目录Cairo、Cg、Gtk、Mac、Qt、Win、Wx分别提供了
GraphicsContext类部分方法的兑现,而集体的贯彻则以webcore\platform\graphics
\GraphicsContext.cpp中提供。

里面我们充分值得关注之措施来drawText与drawImage,其实现如下:

void
GraphicsContext::drawText(const TextRun& run, const IntPoint& point, int
from, int to)

{

if
(paintingDisabled())

return;

font().drawText(this,
run, point, from, to);

}

void
GraphicsContext::drawImage(Image* image, const FloatRect& dest, const
FloatRect& src, CompositeOperator op, bool useLowQualityScale)

{

if (paintingDisabled()
|| !image)

return;

float tsw =
src.width();

float tsh =
src.height();

float tw =
dest.width();

float th =
dest.height();

if (tsw == -1)

tsw =
image->width();

if (tsh == -1)

tsh =
image->height();

if (tw == -1)

tw =
image->width();

if (th == -1)

th =
image->height();

if
(useLowQualityScale) {

save();

setUseLowQualityImageInterpolation(true);

}

image->draw(this,
FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(),
FloatSize(tsw, tsh)), op);

if
(useLowQualityScale)

restore();

}

极端
终的贯彻转交给类Font、Image的法子drawText、draw来贯彻,而不同实现而Cairo、Cg、Gtk、Mac、Qt、Win、Wx则会
针对类Font、Image分别提供部分对应之兑现,而国有的贯彻则当webcore\platform\graphics\Font.cpp及
Image.cpp中提供。

3、不同平台GraphicsContext实例创建和以

GraphicsContext
创建的机会往往在针对诺平台的WebView获得Paint消息事件不时,进而以欠GraphicsContext类实例传递给FrameView及其不同的
RenderObject实例,由不同之RenderObject实例来决定究竟哪来展示我的情,而GraphicsContext类实例提供了各个
种的来得文字、图形、图像的艺术以供RenderObject实例调用。其调整用干多跟Gecko中的差Frame对象下
nsIRenderingContext接口方法类似。

创建GraphicsContext实例的演示如下:

//Gtk

static gboolean
webkit_web_view_expose_event(GtkWidget* widget, GdkEventExpose*
event)

{

WebKitWebView*
webView = WEBKIT_WEB_VIEW(widget);

WebKitWebViewPrivate*
priv = webView->priv;

Frame* frame =
core(webView)->mainFrame();

GdkRectangle
clip;

gdk_region_get_clipbox(event->region,
&clip);

cairo_t* cr =
gdk_cairo_create(event->window);

GraphicsContext
ctx(cr);

ctx.setGdkExposeEvent(event);

if
(frame->contentRenderer() && frame->view()) {

frame->view()->layoutIfNeededRecursive();

if
(priv->transparent) {

cairo_save(cr);

cairo_set_operator(cr,
CAIRO_OPERATOR_CLEAR);

cairo_paint(cr);

cairo_restore(cr);

}

frame->view()->paint(&ctx,
clip);

}

cairo_destroy(cr);

return FALSE;

}

//win

void
WebView::paintIntoBackingStore(FrameView* frameView, HDC bitmapDC,
const IntRect& dirtyRect)

{

LOCAL_GDI_COUNTER(0,
__FUNCTION__);

RECT rect =
dirtyRect;

#if
FLASH_BACKING_STORE_REDRAW

HDC dc =
::GetDC(m_viewWindow);

OwnPtr yellowBrush =
CreateSolidBrush(#ffff00);

FillRect(dc, &rect,
yellowBrush.get());

GdiFlush();

Sleep(50);

paintIntoWindow(bitmapDC,
dc, dirtyRect);

::ReleaseDC(m_viewWindow,
dc);

#endif

FillRect(bitmapDC,
&rect, (HBRUSH)GetStockObject(WHITE_BRUSH));

if (frameView &&
frameView->frame() && frameView->frame()->contentRenderer())
{

GraphicsContext
gc(bitmapDC);

gc.save();

gc.clip(dirtyRect);

frameView->paint(&gc,
dirtyRect);

gc.restore();

}

}

//wx

void
wxWebView::OnPaint(wxPaintEvent& event)

{

if (m_beingDestroyed
|| !m_impl->frame->view() || !m_impl->frame)

return;

wxAutoBufferedPaintDC
dc(this);

if (IsShown() &&
m_impl->frame && m_impl->frame->document()) {

#if USE(WXGC)

wxGCDC
gcdc(dc);

#endif

if (dc.IsOk())
{

wxRect paintRect =
GetUpdateRegion().GetBox();

WebCore::IntSize
offset = m_impl->frame->view()->scrollOffset();

#if USE(WXGC)

gcdc.SetDeviceOrigin(-offset.width(),
-offset.height());

#endif

dc.SetDeviceOrigin(-offset.width(),
-offset.height());

paintRect.Offset(offset.width(),
offset.height());

#if USE(WXGC)

WebCore::GraphicsContext*
gc = new WebCore::GraphicsContext(&gcdc);

#else

WebCore::GraphicsContext*
gc = new WebCore::GraphicsContext((wxWindowDC*)&dc);

#endif

if (gc &&
m_impl->frame->contentRenderer()) {

if
(m_impl->frame->view()->needsLayout())

m_impl->frame->view()->layout();

m_impl->frame->paint(gc,
paintRect);

}

}

}

}

//Qt

void
QWebFrame::render(QPainter *painter, const QRegion &clip)

{

if
(!d->frame->view() || !d->frame->contentRenderer())

return;

d->frame->view()->layoutIfNeededRecursive();

GraphicsContext
ctx(painter);

QVector vector =
clip.rects();

WebCore::FrameView*
view = d->frame->view();

for (int i = 0; i
<>paint(&ctx, vector.at(i));

}

/*!

Render the frame into
\a painter.

*/

void
QWebFrame::render(QPainter *painter)

{

if
(!d->frame->view() || !d->frame->contentRenderer())

return;

d->frame->view()->layoutIfNeededRecursive();

GraphicsContext
ctx(painter);

WebCore::FrameView*
view = d->frame->view();

view->paint(&ctx,
view->frameGeometry());

}

4、WebKit 3D
Port实现

于Clutter WebKit
port中提供了WebKit 对3D
Port的支持和落实,其实现类似于Gtk+/Cairo图形库的贯彻,但那个3D效果无非实现以Port层,没有对页面上之要素而文、图像实现3D效果支持。

此只是略的刺探WebKit中什么整合不同之图形库及其与WebCore的并行。要想更尖锐之垂询页面上的亲笔、图形、图像究竟是怎样展示出的,则需更进一步的对准不同平台库进行学习和了解。

WebKit
中呢支撑canvas标签,该标签提供的接口及Gecko能提供的几乎同一,其现实实现而参看webcore\html
\CanvasRenderingContext2D.cpp,结合GraphicsContext类的落实,应该能够针对canvas标签的兑现有尽的理
解。

四、总结

实则关于图形库及其使用的情很之几近,而对浏览器内核来讲会针对图形库进行快速利用啊是雅重大的同样组成部分,所以当此所出口到的情节可能只是是有些浅,但想会以这开展一下叩问浏览器内核特别是图形库使用方面的笔触。

五、参考资源

Wiki Rendering
(computer graphics)

Wiki Cairo

Cairo HomePage

Wiki Qt

Wiki GTK+

Wiki wxWidgets

Wiki GDI

Wiki DirectX

Wiki Quartz 2D

Wiki OpenGL

Wiki OpenGL ES

Wiki gif

Wiki jpeg

Wiki png

Clutter Toolkit

Font technology and
Freetype

 


 http://hi.baidu.com/liangyj/blog/item/7693eb292be1a4f999250acc.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注