WebCore:

2008-09-02  David Hyatt  <hyatt@apple.com>

        Add support for canvas text drawing APIs.

        Reviewed by olliej

        Tests added as fast/canvas/canvas-text-*.html

        * DerivedSources.make:
        * WebCore.xcodeproj/project.pbxproj:
        * bindings/js/JSCanvasRenderingContext2DCustom.cpp:
        (WebCore::JSCanvasRenderingContext2D::fillText):
        (WebCore::JSCanvasRenderingContext2D::strokeText):
        * css/CSSStyleSelector.cpp:
        (WebCore::CSSStyleSelector::initForStyleResolve):
        (WebCore::CSSStyleSelector::applyPropertyToStyle):
        * css/CSSStyleSelector.h:
        * html/CanvasRenderingContext2D.cpp:
        (WebCore::CanvasRenderingContext2D::State::State):
        (WebCore::CanvasRenderingContext2D::font):
        (WebCore::CanvasRenderingContext2D::setFont):
        (WebCore::CanvasRenderingContext2D::textAlign):
        (WebCore::CanvasRenderingContext2D::setTextAlign):
        (WebCore::CanvasRenderingContext2D::textBaseline):
        (WebCore::CanvasRenderingContext2D::setTextBaseline):
        (WebCore::CanvasRenderingContext2D::fillText):
        (WebCore::CanvasRenderingContext2D::strokeText):
        (WebCore::CanvasRenderingContext2D::measureText):
        (WebCore::CanvasRenderingContext2D::drawTextInternal):
        (WebCore::CanvasRenderingContext2D::accessFont):
        * html/CanvasRenderingContext2D.h:
        * html/CanvasRenderingContext2D.idl:
        * html/TextMetrics.h: Added.
        (WebCore::TextMetrics::create):
        (WebCore::TextMetrics::width):
        (WebCore::TextMetrics::setWidth):
        (WebCore::TextMetrics::TextMetrics):
        * html/TextMetrics.idl: Added.
        * platform/graphics/Font.cpp:
        (WebCore::Font::lineGap):
        * platform/graphics/Font.h:
        * platform/graphics/GraphicsContext.cpp:
        (WebCore::GraphicsContext::drawBidiText):
        * platform/graphics/GraphicsContext.h:
        * platform/graphics/GraphicsTypes.cpp:
        (WebCore::textAlignName):
        (WebCore::parseTextAlign):
        (WebCore::textBaselineName):
        (WebCore::parseTextBaseline):
        * platform/graphics/GraphicsTypes.h:
        (WebCore::):

LayoutTests:

2008-09-02  David Hyatt  <hyatt@apple.com>

        Add support for the canvas text APIs.

        Reviewed by olliej

        * fast/canvas/canvas-text-alignment.html: Added.
        * fast/canvas/canvas-text-baseline.html: Added.
        * platform/mac/fast/canvas/canvas-text-alignment-expected.checksum: Added.
        * platform/mac/fast/canvas/canvas-text-alignment-expected.png: Added.
        * platform/mac/fast/canvas/canvas-text-alignment-expected.txt: Added.
        * platform/mac/fast/canvas/canvas-text-baseline-expected.checksum: Added.
        * platform/mac/fast/canvas/canvas-text-baseline-expected.png: Added.
        * platform/mac/fast/canvas/canvas-text-baseline-expected.txt: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@36060 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index ac6206a..82e0d92 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,18 @@
+2008-09-02  David Hyatt  <hyatt@apple.com>
+
+        Add support for the canvas text APIs.
+
+        Reviewed by olliej
+
+        * fast/canvas/canvas-text-alignment.html: Added.
+        * fast/canvas/canvas-text-baseline.html: Added.
+        * platform/mac/fast/canvas/canvas-text-alignment-expected.checksum: Added.
+        * platform/mac/fast/canvas/canvas-text-alignment-expected.png: Added.
+        * platform/mac/fast/canvas/canvas-text-alignment-expected.txt: Added.
+        * platform/mac/fast/canvas/canvas-text-baseline-expected.checksum: Added.
+        * platform/mac/fast/canvas/canvas-text-baseline-expected.png: Added.
+        * platform/mac/fast/canvas/canvas-text-baseline-expected.txt: Added.
+
 2008-09-03  Adele Peterson  <adele@apple.com>
 
         Reviewed by Darin Adler.
diff --git a/LayoutTests/fast/canvas/canvas-text-alignment.html b/LayoutTests/fast/canvas/canvas-text-alignment.html
new file mode 100644
index 0000000..efb1264
--- /dev/null
+++ b/LayoutTests/fast/canvas/canvas-text-alignment.html
@@ -0,0 +1,81 @@
+<html>
+<body>
+<canvas id="canvas" width=600 height=600 style="border:5px solid black">
+<script>
+var ctx = document.getElementById('canvas').getContext('2d');
+var lingrad = ctx.createLinearGradient(0,0,600,600);
+lingrad.addColorStop(0, '#00ABEB');
+lingrad.addColorStop(1.0, '#fff');
+
+var x = 10;
+var y = 30;
+
+ctx.font = "32px 'Times New Roman'";
+ctx.fillText("Normal Fill Text", x, y);
+
+y += 40;
+
+ctx.lineWidth = 2;
+ctx.strokeText("Normal Stroke Text", x, y);
+
+y += 40;
+
+ctx.fillStyle = lingrad;
+ctx.fillText("Gradient Fill Text", x, y);
+
+y += 40;
+
+ctx.strokeStyle = lingrad;
+ctx.strokeText("Gradient Stroke Text", x, y);
+
+ctx.textAlign = "end";
+
+x = 590;
+y += 40;
+
+ctx.fillStyle = 'black';
+ctx.fillText("Normal Fill Text", x, y);
+
+y += 40;
+
+ctx.strokeStyle = 'black';
+ctx.lineWidth = 2;
+ctx.strokeText("Normal Stroke Text", x, y);
+
+y += 40;
+
+ctx.fillStyle = lingrad;
+ctx.fillText("Gradient Fill Text", x, y);
+
+y += 40;
+
+ctx.strokeStyle = lingrad;
+ctx.strokeText("Gradient Stroke Text", x, y);
+
+y += 40;
+x = 300;
+
+ctx.textAlign = "center";
+
+ctx.fillStyle = 'black';
+ctx.fillText("Normal Fill Text", x, y);
+
+y += 40;
+
+ctx.strokeStyle = 'black';
+ctx.lineWidth = 2;
+ctx.strokeText("Normal Stroke Text", x, y);
+
+y += 40;
+
+ctx.fillStyle = lingrad;
+ctx.fillText("Gradient Fill Text", x, y);
+
+y += 40;
+
+ctx.strokeStyle = lingrad;
+ctx.strokeText("Gradient Stroke Text", x, y);
+
+y += 40;
+
+</script>
diff --git a/LayoutTests/fast/canvas/canvas-text-baseline.html b/LayoutTests/fast/canvas/canvas-text-baseline.html
new file mode 100644
index 0000000..c2471a9
--- /dev/null
+++ b/LayoutTests/fast/canvas/canvas-text-baseline.html
@@ -0,0 +1,42 @@
+<html>
+<body>
+<canvas id="canvas" width=600 height=300 style="border:5px solid black">
+<script>
+var ctx = document.getElementById('canvas').getContext('2d');
+
+var x = 10;
+var y = 150;
+
+ctx.lineWidth = 1;
+ctx.beginPath();
+ctx.moveTo(0, 150);
+ctx.lineTo(600, 150);
+ctx.closePath();
+ctx.stroke();
+
+ctx.font = "32px 'Times New Roman'";
+
+var text = "Baseline";
+var w = ctx.measureText(text).width;
+ctx.fillText(text, x, y);
+x += w + 10;
+
+text = "Top";
+ctx.textBaseline = "top";
+w = ctx.measureText(text).width;
+ctx.fillText(text, x, y);
+x += w + 10;
+
+text = "Bottom";
+ctx.textBaseline = "bottom";
+w = ctx.measureText(text).width;
+ctx.fillText(text, x, y);
+x += w + 10;
+
+text = "Middle";
+ctx.textBaseline = "middle";
+w = ctx.measureText(text).width;
+ctx.fillText(text, x, y);
+x += w + 10;
+
+</script>
diff --git a/LayoutTests/platform/mac/fast/canvas/canvas-text-alignment-expected.checksum b/LayoutTests/platform/mac/fast/canvas/canvas-text-alignment-expected.checksum
new file mode 100644
index 0000000..3ef4d36
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/canvas/canvas-text-alignment-expected.checksum
@@ -0,0 +1 @@
+edadf21d5093079a7b4488e0fe4ed7d1
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/canvas/canvas-text-alignment-expected.png b/LayoutTests/platform/mac/fast/canvas/canvas-text-alignment-expected.png
new file mode 100644
index 0000000..357e847
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/canvas/canvas-text-alignment-expected.png
Binary files differ
diff --git a/LayoutTests/platform/mac/fast/canvas/canvas-text-alignment-expected.txt b/LayoutTests/platform/mac/fast/canvas/canvas-text-alignment-expected.txt
new file mode 100644
index 0000000..e2b0b73
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/canvas/canvas-text-alignment-expected.txt
@@ -0,0 +1,6 @@
+layer at (0,0) size 785x626
+  RenderView at (0,0) size 785x600
+layer at (0,0) size 785x626
+  RenderBlock {HTML} at (0,0) size 785x626
+    RenderBody {BODY} at (8,8) size 769x610
+      RenderHTMLCanvas {CANVAS} at (0,0) size 610x610 [border: (5px solid #000000)]
diff --git a/LayoutTests/platform/mac/fast/canvas/canvas-text-baseline-expected.checksum b/LayoutTests/platform/mac/fast/canvas/canvas-text-baseline-expected.checksum
new file mode 100644
index 0000000..adbae97
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/canvas/canvas-text-baseline-expected.checksum
@@ -0,0 +1 @@
+684a99291e21e2a2013e810f5cc8e50e
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/fast/canvas/canvas-text-baseline-expected.png b/LayoutTests/platform/mac/fast/canvas/canvas-text-baseline-expected.png
new file mode 100644
index 0000000..04c8d0e
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/canvas/canvas-text-baseline-expected.png
Binary files differ
diff --git a/LayoutTests/platform/mac/fast/canvas/canvas-text-baseline-expected.txt b/LayoutTests/platform/mac/fast/canvas/canvas-text-baseline-expected.txt
new file mode 100644
index 0000000..6606240
--- /dev/null
+++ b/LayoutTests/platform/mac/fast/canvas/canvas-text-baseline-expected.txt
@@ -0,0 +1,6 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderHTMLCanvas {CANVAS} at (0,0) size 610x310 [border: (5px solid #000000)]
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 5dd6189..55bf5bb 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,55 @@
+2008-09-02  David Hyatt  <hyatt@apple.com>
+
+        Add support for canvas text drawing APIs.
+
+        Reviewed by olliej
+
+        Tests added as fast/canvas/canvas-text-*.html
+
+        * DerivedSources.make:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/JSCanvasRenderingContext2DCustom.cpp:
+        (WebCore::JSCanvasRenderingContext2D::fillText):
+        (WebCore::JSCanvasRenderingContext2D::strokeText):
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::initForStyleResolve):
+        (WebCore::CSSStyleSelector::applyPropertyToStyle):
+        * css/CSSStyleSelector.h:
+        * html/CanvasRenderingContext2D.cpp:
+        (WebCore::CanvasRenderingContext2D::State::State):
+        (WebCore::CanvasRenderingContext2D::font):
+        (WebCore::CanvasRenderingContext2D::setFont):
+        (WebCore::CanvasRenderingContext2D::textAlign):
+        (WebCore::CanvasRenderingContext2D::setTextAlign):
+        (WebCore::CanvasRenderingContext2D::textBaseline):
+        (WebCore::CanvasRenderingContext2D::setTextBaseline):
+        (WebCore::CanvasRenderingContext2D::fillText):
+        (WebCore::CanvasRenderingContext2D::strokeText):
+        (WebCore::CanvasRenderingContext2D::measureText):
+        (WebCore::CanvasRenderingContext2D::drawTextInternal):
+        (WebCore::CanvasRenderingContext2D::accessFont):
+        * html/CanvasRenderingContext2D.h:
+        * html/CanvasRenderingContext2D.idl:
+        * html/TextMetrics.h: Added.
+        (WebCore::TextMetrics::create):
+        (WebCore::TextMetrics::width):
+        (WebCore::TextMetrics::setWidth):
+        (WebCore::TextMetrics::TextMetrics):
+        * html/TextMetrics.idl: Added.
+        * platform/graphics/Font.cpp:
+        (WebCore::Font::lineGap):
+        * platform/graphics/Font.h:
+        * platform/graphics/GraphicsContext.cpp:
+        (WebCore::GraphicsContext::drawBidiText):
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/GraphicsTypes.cpp:
+        (WebCore::textAlignName):
+        (WebCore::parseTextAlign):
+        (WebCore::textBaselineName):
+        (WebCore::parseTextBaseline):
+        * platform/graphics/GraphicsTypes.h:
+        (WebCore::):
+
 2008-09-03  John Sullivan  <sullivan@apple.com>
 
         Fixed <rdar://problem/6193022> <rdar://problem/6193022> Crash occurs at WebCore::AnimationBase::propertiesEqual () after certain steps
diff --git a/WebCore/DerivedSources.make b/WebCore/DerivedSources.make
index 80315a2..e9b38c4 100644
--- a/WebCore/DerivedSources.make
+++ b/WebCore/DerivedSources.make
@@ -337,6 +337,7 @@
     StyleSheetList \
     Text \
     TextEvent \
+    TextMetrics \
     TimeRanges \
     TreeWalker \
     UIEvent \
diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj
index fc341cef..26d7aeb 100644
--- a/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -3969,6 +3969,10 @@
 		BCEF444D0E674628001C1287 /* StyleCachedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEF444C0E674628001C1287 /* StyleCachedImage.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		BCEF447A0E6747D0001C1287 /* StyleCachedImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEF44790E6747D0001C1287 /* StyleCachedImage.cpp */; };
 		BCEF447D0E674806001C1287 /* StyleGeneratedImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEF447C0E674806001C1287 /* StyleGeneratedImage.cpp */; };
+		BCEF45400E676AC1001C1287 /* TextMetrics.idl in Resources */ = {isa = PBXBuildFile; fileRef = BCEF453F0E676AC1001C1287 /* TextMetrics.idl */; };
+		BCEF45E90E687767001C1287 /* TextMetrics.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEF45E80E687767001C1287 /* TextMetrics.h */; };
+		BCEF45F50E687B5C001C1287 /* JSTextMetrics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEF45F30E687B5C001C1287 /* JSTextMetrics.cpp */; };
+		BCEF45F60E687B5C001C1287 /* JSTextMetrics.h in Headers */ = {isa = PBXBuildFile; fileRef = BCEF45F40E687B5C001C1287 /* JSTextMetrics.h */; };
 		BCEFAF4E0C317E6900FA81F6 /* JSEventCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEFAF4D0C317E6900FA81F6 /* JSEventCustom.cpp */; };
 		BCEFE1E50DCA5F3300739219 /* JSXSLTProcessorCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEFE1E40DCA5F3300739219 /* JSXSLTProcessorCustom.cpp */; };
 		BCEFE1EA0DCA5F6400739219 /* JSXSLTProcessor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCEFE1E80DCA5F6400739219 /* JSXSLTProcessor.cpp */; };
@@ -8401,6 +8405,10 @@
 		BCEF444C0E674628001C1287 /* StyleCachedImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StyleCachedImage.h; path = style/StyleCachedImage.h; sourceTree = "<group>"; };
 		BCEF44790E6747D0001C1287 /* StyleCachedImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StyleCachedImage.cpp; path = style/StyleCachedImage.cpp; sourceTree = "<group>"; };
 		BCEF447C0E674806001C1287 /* StyleGeneratedImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StyleGeneratedImage.cpp; path = style/StyleGeneratedImage.cpp; sourceTree = "<group>"; };
+		BCEF453F0E676AC1001C1287 /* TextMetrics.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = TextMetrics.idl; sourceTree = "<group>"; };
+		BCEF45E80E687767001C1287 /* TextMetrics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextMetrics.h; sourceTree = "<group>"; };
+		BCEF45F30E687B5C001C1287 /* JSTextMetrics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTextMetrics.cpp; sourceTree = "<group>"; };
+		BCEF45F40E687B5C001C1287 /* JSTextMetrics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTextMetrics.h; sourceTree = "<group>"; };
 		BCEFAF4D0C317E6900FA81F6 /* JSEventCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSEventCustom.cpp; sourceTree = "<group>"; };
 		BCEFE1DC0DCA5CFD00739219 /* XSLTProcessor.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = XSLTProcessor.idl; sourceTree = "<group>"; };
 		BCEFE1E40DCA5F3300739219 /* JSXSLTProcessorCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSXSLTProcessorCustom.cpp; sourceTree = "<group>"; };
@@ -10919,6 +10927,8 @@
 				E446139C0CD6331000FADA75 /* MediaError.idl */,
 				E4D4ABE00D7542F000F96869 /* PreloadScanner.cpp */,
 				E4D4ABE10D7542F100F96869 /* PreloadScanner.h */,
+				BCEF45E80E687767001C1287 /* TextMetrics.h */,
+				BCEF453F0E676AC1001C1287 /* TextMetrics.idl */,
 				E446139D0CD6331000FADA75 /* TimeRanges.cpp */,
 				E446139E0CD6331000FADA75 /* TimeRanges.h */,
 				E446139F0CD6331000FADA75 /* TimeRanges.idl */,
@@ -10948,6 +10958,8 @@
 		A83B79080CCAFF2B000B0825 /* HTML */ = {
 			isa = PBXGroup;
 			children = (
+				BCEF45F30E687B5C001C1287 /* JSTextMetrics.cpp */,
+				BCEF45F40E687B5C001C1287 /* JSTextMetrics.h */,
 				65DF323309D1DE65000BE325 /* JSCanvasGradient.cpp */,
 				65DF323409D1DE65000BE325 /* JSCanvasGradient.h */,
 				65DF323509D1DE65000BE325 /* JSCanvasPattern.cpp */,
@@ -15489,6 +15501,8 @@
 				BCEF444A0E6745E0001C1287 /* StyleGeneratedImage.h in Headers */,
 				BCEF444D0E674628001C1287 /* StyleCachedImage.h in Headers */,
 				A88FE3340E5EEE87008D8C0F /* GraphicsContextPrivate.h in Headers */,
+				BCEF45E90E687767001C1287 /* TextMetrics.h in Headers */,
+				BCEF45F60E687B5C001C1287 /* JSTextMetrics.h in Headers */,
 				AB014DE40E689A4300E10445 /* TextControlInnerElements.h in Headers */,
 				316FE1120E6E1DA700BF6088 /* AnimationBase.h in Headers */,
 				316FE1140E6E1DA700BF6088 /* AnimationController.h in Headers */,
@@ -15608,6 +15622,7 @@
 				85136CA80AED665900F90A3D /* westResizeCursor.png in Resources */,
 				1AB1AE7A0C051FDE00139F4F /* zoomInCursor.png in Resources */,
 				1AB1AE7B0C051FDE00139F4F /* zoomOutCursor.png in Resources */,
+				BCEF45400E676AC1001C1287 /* TextMetrics.idl in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -17282,6 +17297,7 @@
 				BCEF43E00E674110001C1287 /* NinePieceImage.cpp in Sources */,
 				BCEF447A0E6747D0001C1287 /* StyleCachedImage.cpp in Sources */,
 				BCEF447D0E674806001C1287 /* StyleGeneratedImage.cpp in Sources */,
+				BCEF45F50E687B5C001C1287 /* JSTextMetrics.cpp in Sources */,
 				AB014DE30E689A4300E10445 /* TextControlInnerElements.cpp in Sources */,
 				316FE1110E6E1DA700BF6088 /* AnimationBase.cpp in Sources */,
 				316FE1130E6E1DA700BF6088 /* AnimationController.cpp in Sources */,
diff --git a/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp
index 37e254f..adf7927 100644
--- a/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp
+++ b/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp
@@ -351,4 +351,40 @@
     return jsUndefined();
 }
 
+JSValue* JSCanvasRenderingContext2D::fillText(ExecState* exec, const ArgList& args)
+{ 
+    CanvasRenderingContext2D* context = impl();
+
+    // string arg = text to draw
+    // number arg = x
+    // number arg = y
+    // optional number arg = maxWidth
+    if (args.size() < 3 || args.size() > 4)
+        return throwError(exec, SyntaxError);
+    
+    if (args.size() == 4)
+        context->fillText(args.at(exec, 0)->toString(exec), args.at(exec, 1)->toFloat(exec), args.at(exec, 2)->toFloat(exec), args.at(exec, 3)->toFloat(exec));
+    else
+        context->fillText(args.at(exec, 0)->toString(exec), args.at(exec, 1)->toFloat(exec), args.at(exec, 2)->toFloat(exec));
+    return jsUndefined();
+}
+
+JSValue* JSCanvasRenderingContext2D::strokeText(ExecState* exec, const ArgList& args)
+{ 
+    CanvasRenderingContext2D* context = impl();
+
+    // string arg = text to draw
+    // number arg = x
+    // number arg = y
+    // optional number arg = maxWidth
+    if (args.size() < 3 || args.size() > 4)
+        return throwError(exec, SyntaxError);
+    
+    if (args.size() == 4)
+        context->strokeText(args.at(exec, 0)->toString(exec), args.at(exec, 1)->toFloat(exec), args.at(exec, 2)->toFloat(exec), args.at(exec, 3)->toFloat(exec));
+    else
+        context->strokeText(args.at(exec, 0)->toString(exec), args.at(exec, 1)->toFloat(exec), args.at(exec, 2)->toFloat(exec));
+    return jsUndefined();
+}
+
 } // namespace WebCore
diff --git a/WebCore/css/CSSStyleSelector.cpp b/WebCore/css/CSSStyleSelector.cpp
index 29553f2..27c9676 100644
--- a/WebCore/css/CSSStyleSelector.cpp
+++ b/WebCore/css/CSSStyleSelector.cpp
@@ -751,10 +751,10 @@
 {
     m_checker.m_pseudoStyle = pseudoID;
 
-    m_parentNode = e->parentNode();
+    m_parentNode = e ? e->parentNode() : 0;
 
 #if ENABLE(SVG)
-    if (!m_parentNode && e->isSVGElement() && e->isShadowNode())
+    if (!m_parentNode && e && e->isSVGElement() && e->isShadowNode())
         m_parentNode = e->shadowParentNode();
 #endif
 
@@ -2530,6 +2530,14 @@
     }
 }
 
+void CSSStyleSelector::applyPropertyToStyle(int id, CSSValue *value, RenderStyle* style)
+{
+    initElementAndPseudoState(0);
+    initForStyleResolve(0, style);
+    m_style = style;
+    applyProperty(id, value);
+}
+
 void CSSStyleSelector::applyProperty(int id, CSSValue *value)
 {
     CSSPrimitiveValue* primitiveValue = 0;
diff --git a/WebCore/css/CSSStyleSelector.h b/WebCore/css/CSSStyleSelector.h
index b3a5431..e2fd1e0 100644
--- a/WebCore/css/CSSStyleSelector.h
+++ b/WebCore/css/CSSStyleSelector.h
@@ -112,6 +112,8 @@
         void setStyle(RenderStyle* s) { m_style = s; } // Used by the document when setting up its root style.
         void setFontSize(FontDescription&, float size);
 
+        void applyPropertyToStyle(int id, CSSValue*, RenderStyle*);
+
     private:
         float getComputedSizeFromSpecifiedSize(bool isAbsoluteSize, float specifiedSize);
 
diff --git a/WebCore/html/CanvasRenderingContext2D.cpp b/WebCore/html/CanvasRenderingContext2D.cpp
index e0ae672..87cb755 100644
--- a/WebCore/html/CanvasRenderingContext2D.cpp
+++ b/WebCore/html/CanvasRenderingContext2D.cpp
@@ -36,6 +36,8 @@
 #include "CanvasPattern.h"
 #include "CanvasPixelArray.h"
 #include "CanvasStyle.h"
+#include "CSSPropertyNames.h"
+#include "CSSStyleSelector.h"
 #include "Document.h"
 #include "ExceptionCode.h"
 #include "FloatConversion.h"
@@ -52,6 +54,7 @@
 #include "RenderHTMLCanvas.h"
 #include "SecurityOrigin.h"
 #include "Settings.h"
+#include "TextMetrics.h"
 #include <kjs/interpreter.h>
 #include <stdio.h>
 #include <wtf/MathExtras.h>
@@ -65,13 +68,14 @@
 #include <cairo.h>
 #endif
 
-using std::max;
-using std::min;
+using namespace std;
 
 namespace WebCore {
 
 using namespace HTMLNames;
 
+const char* defaultFont = "10px sans-serif";
+
 CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas)
     : m_canvas(canvas)
     , m_stateStack(1)
@@ -105,6 +109,10 @@
     , m_shadowColor("black")
     , m_globalAlpha(1)
     , m_globalComposite(CompositeSourceOver)
+    , m_textAlign(StartTextAlign)
+    , m_textBaseline(AlphabeticTextBaseline)
+    , m_unparsedFont(defaultFont)
+    , m_realizedFont(false)
 {
 }
 
@@ -1146,4 +1154,205 @@
     buffer->putImageData(data, sourceRect, destPoint);
 }
 
+String CanvasRenderingContext2D::font() const
+{
+    return state().m_unparsedFont;
+}
+
+void CanvasRenderingContext2D::setFont(const String& newFont)
+{
+    RefPtr<CSSMutableStyleDeclaration> tempDecl = CSSMutableStyleDeclaration::create();
+    CSSParser parser(!m_canvas->document()->inCompatMode()); // Use the parse mode of the canvas' document when parsing CSS.
+        
+    String declarationText("font: ");
+    declarationText += newFont;
+    parser.parseDeclaration(tempDecl.get(), declarationText);
+    if (!tempDecl->length())
+        return;
+            
+    // The parse succeeded.
+    state().m_unparsedFont = newFont;
+    
+    // Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work
+    // relative to the canvas.
+    RenderArena* arena = m_canvas->document()->renderArena();
+    RenderStyle* newStyle = new (arena) RenderStyle();
+    newStyle->ref();
+    if (m_canvas->computedStyle())
+        newStyle->setFontDescription(m_canvas->computedStyle()->fontDescription());
+
+    // Now map the font property into the style.
+    CSSStyleSelector* styleSelector = m_canvas->document()->styleSelector();
+    styleSelector->applyPropertyToStyle(CSSPropertyFont, tempDecl->getPropertyCSSValue(CSSPropertyFont).get(), newStyle);
+    
+    state().m_font = newStyle->font();
+    state().m_font.update(styleSelector->fontSelector());
+    state().m_realizedFont = true;
+
+    newStyle->deref(arena);
+    
+    // Set the font in the graphics context.
+    GraphicsContext* c = drawingContext();
+    if (!c)
+        return;
+    c->setFont(state().m_font);
+}
+        
+String CanvasRenderingContext2D::textAlign() const
+{
+    return textAlignName(state().m_textAlign);
+}
+
+void CanvasRenderingContext2D::setTextAlign(const String& s)
+{
+    TextAlign align;
+    if (!parseTextAlign(s, align))
+        return;
+    state().m_textAlign = align;
+}
+        
+String CanvasRenderingContext2D::textBaseline() const
+{
+    return textBaselineName(state().m_textBaseline);
+}
+
+void CanvasRenderingContext2D::setTextBaseline(const String& s)
+{
+    TextBaseline baseline;
+    if (!parseTextBaseline(s, baseline))
+        return;
+    state().m_textBaseline = baseline;
+}
+
+void CanvasRenderingContext2D::fillText(const String& text, float x, float y)
+{
+    drawTextInternal(text, x, y, true);
+}
+
+void CanvasRenderingContext2D::fillText(const String& text, float x, float y, float maxWidth)
+{
+    drawTextInternal(text, x, y, true, maxWidth, true);
+}
+
+void CanvasRenderingContext2D::strokeText(const String& text, float x, float y)
+{
+    drawTextInternal(text, x, y, false);
+}
+
+void CanvasRenderingContext2D::strokeText(const String& text, float x, float y, float maxWidth)
+{
+    drawTextInternal(text, x, y, false, maxWidth, true);
+}
+
+PassRefPtr<TextMetrics> CanvasRenderingContext2D::measureText(const String& text)
+{
+    RefPtr<TextMetrics> metrics = TextMetrics::create();
+    metrics->setWidth(accessFont().width(TextRun(text.characters(), text.length())));
+    return metrics;
+}
+
+void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth, bool useMaxWidth)
+{
+    GraphicsContext* c = drawingContext();
+    if (!c)
+        return;
+    
+    const Font& font = accessFont();
+
+    // FIXME: Handle maxWidth.
+    // FIXME: Need to turn off font smoothing.
+
+    bool rtl = m_canvas->computedStyle() ? m_canvas->computedStyle()->direction() == RTL : false;
+    bool override = m_canvas->computedStyle() ? m_canvas->computedStyle()->unicodeBidi() == Override : false;
+
+    unsigned length = text.length();
+    const UChar* string = text.characters();
+    TextRun textRun(string, length, 0, 0, 0, rtl, override, false, false);
+
+    // Draw the item text at the correct point.
+    FloatPoint location(x, y);
+    switch (state().m_textBaseline) {
+        case TopTextBaseline:
+        case HangingTextBaseline:
+            location.setY(y + font.ascent());
+            break;
+        case BottomTextBaseline:
+        case IdeographicTextBaseline:
+            location.setY(y - font.descent());
+            break;
+        case MiddleTextBaseline:
+            location.setY(y - font.descent() + font.height() / 2);
+            break;
+        case AlphabeticTextBaseline:
+        default:
+             // Do nothing.
+            break;
+    }
+    
+    float width = font.width(TextRun(text, false, 0, 0, rtl, override));
+
+    TextAlign align = state().m_textAlign;
+    if (align == StartTextAlign)
+         align = rtl ? RightTextAlign : LeftTextAlign;
+    else if (align == EndTextAlign)
+        align = rtl ? LeftTextAlign : RightTextAlign;
+    
+    switch (align) {
+        case CenterTextAlign:
+            location.setX(location.x() - width / 2);
+            break;
+        case RightTextAlign:
+            location.setX(location.x() - width);
+            break;
+        default:
+            break;
+    }
+    
+    // The slop built in to this mask rect matches the heuristic used in FontCGWin.cpp for GDI text.
+    FloatRect textRect = FloatRect(location.x() - font.height() / 2, location.y() - font.ascent() - font.lineGap(),
+                                   width + font.height(), font.lineSpacing());
+    if (!fill)
+        textRect.inflate(c->strokeThickness() / 2);
+        
+    CanvasStyle* drawStyle = fill ? state().m_fillStyle.get() : state().m_strokeStyle.get();
+    if (drawStyle->canvasGradient() || drawStyle->canvasPattern()) {
+        IntRect maskRect = enclosingIntRect(textRect);
+
+        auto_ptr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size(), false);
+        
+        GraphicsContext* maskImageContext = maskImage->context();
+
+        if (fill)
+            maskImageContext->setFillColor(Color::black);
+        else {
+            maskImageContext->setStrokeColor(Color::black);
+            maskImageContext->setStrokeThickness(c->strokeThickness());
+        }
+
+        maskImageContext->setTextDrawingMode(fill ? cTextFill : cTextStroke);
+        maskImageContext->translate(-maskRect.x(), -maskRect.y());
+        
+        maskImageContext->setFont(font);
+        maskImageContext->drawBidiText(textRun, location);
+        
+        c->save();
+        c->clipToImageBuffer(maskRect, maskImage.get());
+        drawStyle->applyFillColor(c);
+        c->fillRect(maskRect);
+        c->restore();
+
+        return;
+    }
+
+    c->setTextDrawingMode(fill ? cTextFill : cTextStroke);
+    c->drawBidiText(textRun, location);
+}
+
+const Font& CanvasRenderingContext2D::accessFont()
+{
+    if (!state().m_realizedFont)
+        setFont(state().m_unparsedFont);
+    return state().m_font;
+}
+
 } // namespace WebCore
diff --git a/WebCore/html/CanvasRenderingContext2D.h b/WebCore/html/CanvasRenderingContext2D.h
index 9a7fdae..d335629 100644
--- a/WebCore/html/CanvasRenderingContext2D.h
+++ b/WebCore/html/CanvasRenderingContext2D.h
@@ -28,6 +28,7 @@
 
 #include "AffineTransform.h"
 #include "FloatSize.h"
+#include "Font.h"
 #include "GraphicsTypes.h"
 #include "Path.h"
 #include "PlatformString.h"
@@ -48,6 +49,7 @@
     class HTMLImageElement;
     class ImageData;
     class KURL;
+    class TextMetrics;
 
     typedef int ExceptionCode;
 
@@ -176,10 +178,25 @@
         
         void reset();
 
+        String font() const;
+        void setFont(const String&);
+        
+        String textAlign() const;
+        void setTextAlign(const String&);
+        
+        String textBaseline() const;
+        void setTextBaseline(const String&);
+        
+        void fillText(const String& text, float x, float y);
+        void fillText(const String& text, float x, float y, float maxWidth);
+        void strokeText(const String& text, float x, float y);
+        void strokeText(const String& text, float x, float y, float maxWidth);
+        PassRefPtr<TextMetrics> measureText(const String& text);
+
     private:
         struct State {
             State();
-
+            
             RefPtr<CanvasStyle> m_strokeStyle;
             RefPtr<CanvasStyle> m_fillStyle;
             float m_lineWidth;
@@ -192,6 +209,14 @@
             float m_globalAlpha;
             CompositeOperator m_globalComposite;
             AffineTransform m_transform;
+            
+            // Text state.
+            TextAlign m_textAlign;
+            TextBaseline m_textBaseline;
+            
+            String m_unparsedFont;
+            Font m_font;
+            bool m_realizedFont;
         };
         Path m_path;
 
@@ -207,6 +232,10 @@
         void applyStrokePattern();
         void applyFillPattern();
 
+        void drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth = 0, bool useMaxWidth = false);
+
+        const Font& accessFont();
+
 #if ENABLE(DASHBOARD_SUPPORT)
         void clearPathForDashboardBackwardCompatibilityMode();
 #endif
diff --git a/WebCore/html/CanvasRenderingContext2D.idl b/WebCore/html/CanvasRenderingContext2D.idl
index 281b6c2..e1e1e06 100644
--- a/WebCore/html/CanvasRenderingContext2D.idl
+++ b/WebCore/html/CanvasRenderingContext2D.idl
@@ -78,6 +78,14 @@
         void clip();
         boolean isPointInPath(in float x, in float y);
 
+        // text
+        attribute DOMString font;
+        attribute DOMString textAlign;
+        attribute DOMString textBaseline;
+        [Custom] void fillText(/* 4 */);
+        [Custom] void strokeText(/* 4 */);
+        TextMetrics measureText(in DOMString text);
+
         // other
 
         void setAlpha(in float alpha);
diff --git a/WebCore/html/TextMetrics.h b/WebCore/html/TextMetrics.h
new file mode 100644
index 0000000..cc92f1c
--- /dev/null
+++ b/WebCore/html/TextMetrics.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 Apple 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 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 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. 
+ */
+
+#ifndef TextMetrics_h
+#define TextMetrics_h
+
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class TextMetrics : public RefCounted<TextMetrics> {
+public:
+    static PassRefPtr<TextMetrics> create() { return new TextMetrics(); }
+
+    unsigned width() const { return m_width; }
+    void setWidth(float w) { m_width = w; }
+
+private:
+    TextMetrics()
+        : m_width(0)
+    { }
+
+    float m_width;
+};
+
+} // namespace WebCore
+
+#endif // TextMetrics_h
diff --git a/WebCore/html/TextMetrics.idl b/WebCore/html/TextMetrics.idl
new file mode 100644
index 0000000..dc88716
--- /dev/null
+++ b/WebCore/html/TextMetrics.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 Apple 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 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 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. 
+ */
+
+module html {
+
+    interface [
+        GenerateConstructor
+    ] TextMetrics {
+        readonly attribute float width;
+    };
+
+}
diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl
index 948466e..a0ff779 100644
--- a/WebCore/page/DOMWindow.idl
+++ b/WebCore/page/DOMWindow.idl
@@ -275,6 +275,7 @@
         attribute HTMLCollectionConstructor HTMLCollection;
 
         attribute CanvasRenderingContext2DConstructor CanvasRenderingContext2D;
+        attribute TextMetricsConstructor TextMetrics;
 
         attribute EventConstructor Event;
         attribute KeyboardEventConstructor KeyboardEvent;
diff --git a/WebCore/platform/graphics/Font.cpp b/WebCore/platform/graphics/Font.cpp
index 995cac4..eafc11a 100644
--- a/WebCore/platform/graphics/Font.cpp
+++ b/WebCore/platform/graphics/Font.cpp
@@ -531,6 +531,11 @@
     return primaryFont()->lineSpacing();
 }
 
+int Font::lineGap() const
+{
+    return primaryFont()->lineGap();
+}
+
 float Font::xHeight() const
 {
     return primaryFont()->xHeight();
diff --git a/WebCore/platform/graphics/Font.h b/WebCore/platform/graphics/Font.h
index 7a07495..2f70da1 100644
--- a/WebCore/platform/graphics/Font.h
+++ b/WebCore/platform/graphics/Font.h
@@ -119,6 +119,7 @@
     int descent() const;
     int height() const { return ascent() + descent(); }
     int lineSpacing() const;
+    int lineGap() const;
     float xHeight() const;
     unsigned unitsPerEm() const;
     int spaceWidth() const;
diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp
index 9ecb5ea..8abecbf 100644
--- a/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/WebCore/platform/graphics/GraphicsContext.cpp
@@ -298,7 +298,7 @@
     font().drawText(this, run, point, from, to);
 }
 
-void GraphicsContext::drawBidiText(const TextRun& run, const IntPoint& point)
+void GraphicsContext::drawBidiText(const TextRun& run, const FloatPoint& point)
 {
     if (paintingDisabled())
         return;
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index 664274d..2d7c828 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -203,7 +203,7 @@
         void setTextDrawingMode(int);
 
         void drawText(const TextRun&, const IntPoint&, int from = 0, int to = -1);
-        void drawBidiText(const TextRun&, const IntPoint&);
+        void drawBidiText(const TextRun&, const FloatPoint&);
         void drawHighlightForText(const TextRun&, const IntPoint&, int h, const Color& backgroundColor, int from = 0, int to = -1);
 
         FloatRect roundToDevicePixels(const FloatRect&);
diff --git a/WebCore/platform/graphics/GraphicsTypes.cpp b/WebCore/platform/graphics/GraphicsTypes.cpp
index 736356f..761bf40 100644
--- a/WebCore/platform/graphics/GraphicsTypes.cpp
+++ b/WebCore/platform/graphics/GraphicsTypes.cpp
@@ -116,4 +116,74 @@
     return names[join];
 }
 
+String textAlignName(TextAlign align)
+{
+    ASSERT(align >= 0);
+    ASSERT(align < 5);
+    const char* const names[5] = { "start", "end", "left", "center", "right" };
+    return names[align];
+}
+
+bool parseTextAlign(const String& s, TextAlign& align)
+{
+    if (s == "start") {
+        align = StartTextAlign;
+        return true;
+    }
+    if (s == "end") {
+        align = EndTextAlign;
+        return true;
+    }
+    if (s == "left") {
+        align = LeftTextAlign;
+        return true;
+    }
+    if (s == "center") {
+        align = CenterTextAlign;
+        return true;
+    }
+    if (s == "right") {
+        align = RightTextAlign;
+        return true;
+    }
+    return false;
+}
+
+String textBaselineName(TextBaseline baseline)
+{
+    ASSERT(baseline >= 0);
+    ASSERT(baseline < 6);
+    const char* const names[6] = { "alphabetic", "top", "middle", "bottom", "ideographic", "hanging" };
+    return names[baseline];
+}
+
+bool parseTextBaseline(const String& s, TextBaseline& baseline)
+{
+    if (s == "alphabetic") {
+        baseline = AlphabeticTextBaseline;
+        return true;
+    }
+    if (s == "top") {
+        baseline = TopTextBaseline;
+        return true;
+    }
+    if (s == "middle") {
+        baseline = MiddleTextBaseline;
+        return true;
+    }
+    if (s == "bottom") {
+        baseline = BottomTextBaseline;
+        return true;
+    }
+    if (s == "ideographic") {
+        baseline = IdeographicTextBaseline;
+        return true;
+    }
+    if (s == "hanging") {
+        baseline = HangingTextBaseline;
+        return true;
+    }
+    return false;
+}
+
 }
diff --git a/WebCore/platform/graphics/GraphicsTypes.h b/WebCore/platform/graphics/GraphicsTypes.h
index ae59c59..cdf5e31 100644
--- a/WebCore/platform/graphics/GraphicsTypes.h
+++ b/WebCore/platform/graphics/GraphicsTypes.h
@@ -56,6 +56,10 @@
 
     enum HorizontalAlignment { AlignLeft, AlignRight, AlignHCenter };
 
+    enum TextBaseline { AlphabeticTextBaseline, TopTextBaseline, MiddleTextBaseline, BottomTextBaseline, IdeographicTextBaseline, HangingTextBaseline };
+    
+    enum TextAlign { StartTextAlign, EndTextAlign, LeftTextAlign, CenterTextAlign, RightTextAlign };
+
     String compositeOperatorName(CompositeOperator);
     bool parseCompositeOperator(const String&, CompositeOperator&);
 
@@ -65,6 +69,12 @@
     String lineJoinName(LineJoin);
     bool parseLineJoin(const String&, LineJoin&);
 
+    String textAlignName(TextAlign);
+    bool parseTextAlign(const String&, TextAlign&);
+    
+    String textBaselineName(TextBaseline);
+    bool parseTextBaseline(const String&, TextBaseline&);
+
 } // namespace WebCore
 
 #endif