Bug 1108429 part 1 - Add ruby utils for reserving isize of ruby boxes. r=roc
authorXidorn Quan <quanxunzhen@gmail.com>
Fri, 12 Dec 2014 21:30:43 +1100
changeset 247084 a339d7695b60f4946775fac243c42a13aa16d654
parent 247083 79f5c70472823457b8f96bf61459f22be4b9ca63
child 247085 f437602d958dc7b86eafc34728a34f6103f81611
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1108429
milestone37.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1108429 part 1 - Add ruby utils for reserving isize of ruby boxes. r=roc
layout/generic/RubyUtils.cpp
layout/generic/RubyUtils.h
layout/generic/moz.build
new file mode 100644
--- /dev/null
+++ b/layout/generic/RubyUtils.cpp
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "RubyUtils.h"
+#include "nsIFrame.h"
+
+using namespace mozilla;
+
+NS_DECLARE_FRAME_PROPERTY(ReservedISize, nullptr);
+
+union NSCoordValue
+{
+  nscoord mCoord;
+  void* mPointer;
+  static_assert(sizeof(nscoord) <= sizeof(void*),
+                "Cannot store nscoord in pointer");
+};
+
+/* static */ void
+RubyUtils::SetReservedISize(nsIFrame* aFrame, nscoord aISize)
+{
+  MOZ_ASSERT(IsExpandableRubyBox(aFrame));
+  NSCoordValue value = { aISize };
+  aFrame->Properties().Set(ReservedISize(), value.mPointer);
+}
+
+/* static */ void
+RubyUtils::ClearReservedISize(nsIFrame* aFrame)
+{
+  MOZ_ASSERT(IsExpandableRubyBox(aFrame));
+  aFrame->Properties().Remove(ReservedISize());
+}
+
+/* static */ nscoord
+RubyUtils::GetReservedISize(nsIFrame* aFrame)
+{
+  MOZ_ASSERT(IsExpandableRubyBox(aFrame));
+  NSCoordValue value;
+  value.mPointer = aFrame->Properties().Get(ReservedISize());
+  return value.mCoord;
+}
new file mode 100644
--- /dev/null
+++ b/layout/generic/RubyUtils.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_RubyUtils_h_
+#define mozilla_RubyUtils_h_
+
+#include "nsGkAtoms.h"
+#include "nsIFrame.h"
+
+namespace mozilla {
+
+/**
+ * Reserved ISize
+ *
+ * With some exceptions, each ruby internal box has two isizes, which
+ * are the reflowed isize and the final isize. The reflowed isize is
+ * what a box itself needs. It is determined when the box gets reflowed.
+ *
+ * The final isize is what a box should be as the final result. For a
+ * ruby base/text box, the final isize is the size of its ruby column.
+ * For a ruby base/text container, the final isize is the size of its
+ * ruby segment. The final isize is never smaller than the reflowed
+ * isize. It is initially determined when a ruby column/segment gets
+ * fully reflowed, and may be advanced when a box is expanded, e.g.
+ * for justification.
+ *
+ * The difference between the reflowed isize and the final isize is
+ * reserved in the line layout after reflowing a box, hence it is called
+ * "Reserved ISize" here. It is used to expand the ruby boxes from their
+ * reflowed isize to the final isize during alignment of the line.
+ *
+ * There are three exceptions for the final isize:
+ * 1. A ruby text container has a larger final isize only if it is for
+ *    a span or collapsed annotations.
+ * 2. A ruby base container has a larger final isize only if at least
+ *    one of its ruby text containers does.
+ * 3. If a ruby text container has a larger final isize, its children
+ *    must not have.
+ */
+
+class RubyUtils
+{
+public:
+  static inline bool IsExpandableRubyBox(nsIFrame* aFrame)
+  {
+    nsIAtom* type = aFrame->GetType();
+    return type == nsGkAtoms::rubyBaseFrame ||
+           type == nsGkAtoms::rubyTextFrame ||
+           type == nsGkAtoms::rubyBaseContainerFrame ||
+           type == nsGkAtoms::rubyTextContainerFrame;
+  }
+
+  static void SetReservedISize(nsIFrame* aFrame, nscoord aISize);
+  static void ClearReservedISize(nsIFrame* aFrame);
+  static nscoord GetReservedISize(nsIFrame* aFrame);
+};
+
+}
+
+#endif /* !defined(mozilla_RubyUtils_h_) */
--- a/layout/generic/moz.build
+++ b/layout/generic/moz.build
@@ -89,16 +89,17 @@ UNIFIED_SOURCES += [
     'nsSimplePageSequenceFrame.cpp',
     'nsSplittableFrame.cpp',
     'nsSubDocumentFrame.cpp',
     'nsTextFrame.cpp',
     'nsTextFrameUtils.cpp',
     'nsTextRunTransformations.cpp',
     'nsVideoFrame.cpp',
     'nsViewportFrame.cpp',
+    'RubyUtils.cpp',
     'ScrollbarActivity.cpp',
     'StickyScrollContainer.cpp',
     'TextOverflow.cpp',
 ]
 
 # nsLineLayout.cpp needs to be built separately because it uses plarena.h.
 # nsPluginFrame.cpp needs to be built separately because of name clashes in the OS X headers.
 SOURCES += [