diff -ur icu-4.4.orig/source/layout/LEFontInstance.h icu-4.4/source/layout/LEFontInstance.h
--- icu-4.4.orig/source/layout/LEFontInstance.h	2010-03-16 06:15:08.000000000 +0100
+++ icu-4.4/source/layout/LEFontInstance.h	2010-03-26 21:21:59.751040215 +0100
@@ -509,6 +509,10 @@
      */
     static UClassID getStaticClassID();
 
+    /**
+     * Returns true if writing direction is vertical.
+     */
+    virtual inline bool getLayoutDirVertical() const;
 };
 
 inline float LEFontInstance::fixedToFloat(le_int32 fixed)
@@ -521,6 +525,11 @@
     return (le_int32) (theFloat * 65536.0);
 }
 
+inline bool LEFontInstance::getLayoutDirVertical() const
+{
+    return false;
+}
+
 U_NAMESPACE_END
 #endif
 
diff -ur icu-4.4.orig/source/layout/ValueRecords.cpp icu-4.4/source/layout/ValueRecords.cpp
--- icu-4.4.orig/source/layout/ValueRecords.cpp	2010-03-16 06:15:10.000000000 +0100
+++ icu-4.4/source/layout/ValueRecords.cpp	2010-03-26 21:21:59.751040215 +0100
@@ -48,8 +48,12 @@
 
         fontInstance->transformFunits(value, 0, pixels);
 
-        xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
-        yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
+        xPlacementAdjustment += fontInstance->getLayoutDirVertical()
+                                ? -fontInstance->yPixelsToUnits(pixels.fY)
+                                :  fontInstance->xPixelsToUnits(pixels.fX);
+        yPlacementAdjustment += fontInstance->getLayoutDirVertical()
+                                ?  fontInstance->xPixelsToUnits(pixels.fX)
+                                :  fontInstance->yPixelsToUnits(pixels.fY);
     }
 
     if ((valueFormat & vfbYPlacement) != 0) {
@@ -58,8 +62,12 @@
 
         fontInstance->transformFunits(0, value, pixels);
 
-        xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
-        yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
+        xPlacementAdjustment += fontInstance->getLayoutDirVertical()
+                                ? -fontInstance->yPixelsToUnits(pixels.fY)
+                                :  fontInstance->xPixelsToUnits(pixels.fX);
+        yPlacementAdjustment += fontInstance->getLayoutDirVertical()
+                                ?  fontInstance->xPixelsToUnits(pixels.fX)
+                                :  fontInstance->yPixelsToUnits(pixels.fY);
     }
 
     if ((valueFormat & vfbXAdvance) != 0) {
@@ -68,8 +76,12 @@
 
         fontInstance->transformFunits(value, 0, pixels);
 
-        xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
-        yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
+        xAdvanceAdjustment += fontInstance->getLayoutDirVertical()
+                              ?  fontInstance->yPixelsToUnits(pixels.fY)
+                              :  fontInstance->xPixelsToUnits(pixels.fX);
+        yAdvanceAdjustment += fontInstance->getLayoutDirVertical()
+                              ? -fontInstance->xPixelsToUnits(pixels.fX)
+                              :  fontInstance->yPixelsToUnits(pixels.fY);
     }
 
     if ((valueFormat & vfbYAdvance) != 0) {
@@ -78,8 +90,12 @@
 
         fontInstance->transformFunits(0, value, pixels);
 
-        xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
-        yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
+        xAdvanceAdjustment += fontInstance->getLayoutDirVertical()
+                              ?  fontInstance->yPixelsToUnits(pixels.fY)
+                              :  fontInstance->xPixelsToUnits(pixels.fX);
+        yAdvanceAdjustment += fontInstance->getLayoutDirVertical()
+                              ? -fontInstance->xPixelsToUnits(pixels.fX)
+                              :  fontInstance->yPixelsToUnits(pixels.fY);
     }
 
     // FIXME: The device adjustments should really be transformed, but
@@ -96,7 +112,10 @@
                 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
                 le_int16 xAdj = dt->getAdjustment(xppem);
 
-                xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
+                if (fontInstance->getLayoutDirVertical())
+                    yPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
+                else
+                    xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
             }
         }
 
@@ -107,7 +126,10 @@
                 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
                 le_int16 yAdj = dt->getAdjustment(yppem);
 
-                yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
+                if (fontInstance->getLayoutDirVertical())
+                    xPlacementAdjustment -= fontInstance->yPixelsToUnits(yAdj);
+                else
+                    yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
             }
         }
 
@@ -118,7 +140,10 @@
                 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
                 le_int16 xAdj = dt->getAdjustment(xppem);
 
-                xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
+                if (fontInstance->getLayoutDirVertical())
+                    yAdvanceAdjustment -= fontInstance->xPixelsToUnits(xAdj);
+                else
+                    xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
             }
         }
 
@@ -129,7 +154,10 @@
                 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
                 le_int16 yAdj = dt->getAdjustment(yppem);
 
-                yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
+                if (fontInstance->getLayoutDirVertical())
+                    xAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
+                else
+                    yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
             }
         }
     }
@@ -152,8 +180,12 @@
 
         fontInstance->transformFunits(value, 0, pixels);
 
-        xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
-        yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
+        xPlacementAdjustment += fontInstance->getLayoutDirVertical()
+                                ? -fontInstance->yPixelsToUnits(pixels.fY)
+                                :  fontInstance->xPixelsToUnits(pixels.fX);
+        yPlacementAdjustment += fontInstance->getLayoutDirVertical()
+                                ?  fontInstance->xPixelsToUnits(pixels.fX)
+                                :  fontInstance->yPixelsToUnits(pixels.fY);
     }
 
     if ((valueFormat & vfbYPlacement) != 0) {
@@ -162,8 +194,12 @@
 
         fontInstance->transformFunits(0, value, pixels);
 
-        xPlacementAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
-        yPlacementAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
+        xPlacementAdjustment += fontInstance->getLayoutDirVertical()
+                                ? -fontInstance->yPixelsToUnits(pixels.fY)
+                                :  fontInstance->xPixelsToUnits(pixels.fX);
+        yPlacementAdjustment += fontInstance->getLayoutDirVertical()
+                                ?  fontInstance->xPixelsToUnits(pixels.fX)
+                                :  fontInstance->yPixelsToUnits(pixels.fY);
     }
 
     if ((valueFormat & vfbXAdvance) != 0) {
@@ -172,8 +208,12 @@
 
         fontInstance->transformFunits(value, 0, pixels);
 
-        xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
-        yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
+        xAdvanceAdjustment += fontInstance->getLayoutDirVertical()
+                              ?  fontInstance->yPixelsToUnits(pixels.fY)
+                              :  fontInstance->xPixelsToUnits(pixels.fX);
+        yAdvanceAdjustment += fontInstance->getLayoutDirVertical()
+                              ? -fontInstance->xPixelsToUnits(pixels.fX)
+                              :  fontInstance->yPixelsToUnits(pixels.fY);
     }
 
     if ((valueFormat & vfbYAdvance) != 0) {
@@ -182,8 +222,12 @@
 
         fontInstance->transformFunits(0, value, pixels);
 
-        xAdvanceAdjustment += fontInstance->xPixelsToUnits(pixels.fX);
-        yAdvanceAdjustment += fontInstance->yPixelsToUnits(pixels.fY);
+        xAdvanceAdjustment += fontInstance->getLayoutDirVertical()
+                              ?  fontInstance->yPixelsToUnits(pixels.fY)
+                              :  fontInstance->xPixelsToUnits(pixels.fX);
+        yAdvanceAdjustment += fontInstance->getLayoutDirVertical()
+                              ? -fontInstance->xPixelsToUnits(pixels.fX)
+                              :  fontInstance->yPixelsToUnits(pixels.fY);
     }
 
     // FIXME: The device adjustments should really be transformed, but
@@ -200,7 +244,10 @@
                 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
                 le_int16 xAdj = dt->getAdjustment(xppem);
 
-                xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
+                if (fontInstance->getLayoutDirVertical())
+                    yPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
+                else
+                    xPlacementAdjustment += fontInstance->xPixelsToUnits(xAdj);
             }
         }
 
@@ -211,7 +258,10 @@
                 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
                 le_int16 yAdj = dt->getAdjustment(yppem);
 
-                yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
+                if (fontInstance->getLayoutDirVertical())
+                    xPlacementAdjustment -= fontInstance->yPixelsToUnits(yAdj);
+                else
+                    yPlacementAdjustment += fontInstance->yPixelsToUnits(yAdj);
             }
         }
 
@@ -222,7 +272,10 @@
                 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
                 le_int16 xAdj = dt->getAdjustment(xppem);
 
-                xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
+                if (fontInstance->getLayoutDirVertical())
+                    yAdvanceAdjustment -= fontInstance->xPixelsToUnits(xAdj);
+                else
+                    xAdvanceAdjustment += fontInstance->xPixelsToUnits(xAdj);
             }
         }
 
@@ -233,7 +286,10 @@
                 const DeviceTable *dt = (const DeviceTable *) (base + dtOffset);
                 le_int16 yAdj = dt->getAdjustment(yppem);
 
-                yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
+                if (fontInstance->getLayoutDirVertical())
+                    xAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
+                else
+                    yAdvanceAdjustment += fontInstance->yPixelsToUnits(yAdj);
             }
         }
     }
