Commit cf69822f authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

[PE] Don't fragment painting layer of repeating table header/footer in paged media

Previously, to let the painting layer of a repeating table header/footer
in paged media initiate multi-fragment painting, we created fragments
in the painting layer. This caused several problems:

- The fragments didn't have proper fragment clips, causing non-fragmented
  contents to be painted multiple times. It's also not feasible to create
  fragment clips for the forced fragments on the painting layer because
  we couldn't insert them into the clip tree.

- The previous "if (paint_info.FragmentToPaint(layout_table_section_))
  return;" in TableSectionPainter caused nested repeating header/footer
  not repeated.

Now don't fragment painting layer of repeating table header/footer in
paged media. Instead, let the repeating table header/footer repeat by
itself when needed.

Bug: 852773
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_slimming_paint_v2;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: I1172a334b5021eb7e987404bb72d9b841a4d39d4
Reviewed-on: https://chromium-review.googlesource.com/1112578
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: default avatarChris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569901}
parent 2c6ce192
......@@ -1168,9 +1168,11 @@ crbug.com/591099 virtual/layout_ng_experimental/printing/page-count-relayout-shr
crbug.com/591099 virtual/layout_ng_experimental/printing/respect-layout-overflow-from-pagination.html [ Failure ]
crbug.com/824918 virtual/layout_ng_experimental/printing/setPrinting.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/printing/single-line-must-not-be-split-into-two-pages.html [ Failure Timeout ]
crbug.com/591099 virtual/layout_ng_experimental/printing/thead-repeat-in-nested-table.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/printing/tfoot-repeats-at-bottom-of-each-page-multiple-tables.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/printing/thead-repeats-at-top-of-each-page-multiple-tables.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/printing/thead-repeats-at-top-of-each-page.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/printing/thead-repeats-with-translucent-text-and-borders.html [ Failure ]
crbug.com/591099 virtual/layout_ng_experimental/printing/thead-under-multicol.html [ Failure ]
crbug.com/829804 virtual/layout_ng_experimental/printing/webgl-oversized-printing.html [ Skip ]
crbug.com/824918 virtual/layout_ng_experimental/printing/width-overflow.html [ Failure ]
......
layer at (0,0) size 800x600 scrollHeight 2361
LayoutView at (0,0) size 1046x799
layer at (0,0) size 1046x2361 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
LayoutBlockFlow {HTML} at (0,0) size 1046x2361
LayoutBlockFlow {BODY} at (8,8) size 1030x2345
LayoutTable {TABLE} at (0,0) size 138x2345
LayoutTableSection {THEAD} at (0,0) size 138x102
LayoutTableRow {TR} at (0,0) size 138x102
LayoutTableCell {TH} at (0,40) size 138x22 [r=0 c=0 rs=1 cs=1]
LayoutText {#text} at (10,1) size 118x19
text run at (10,1) width 118: "First level header"
LayoutTableSection {TBODY} at (0,102) size 138x2243
LayoutTableRow {TR} at (0,0) size 138x2243
LayoutTableCell {TD} at (0,0) size 138x2243 [r=0 c=0 rs=1 cs=1]
LayoutTable {TABLE} at (1,1) size 136x2241
LayoutTableSection {THEAD} at (0,0) size 136x102
LayoutTableRow {TR} at (0,0) size 136x102
LayoutTableCell {TH} at (0,40) size 136x22 [r=0 c=0 rs=1 cs=1]
LayoutText {#text} at (1,1) size 134x19
text run at (1,1) width 134: "Second level header"
LayoutTableSection {TBODY} at (0,102) size 136x2139
LayoutTableRow {TR} at (0,0) size 136x550
LayoutTableCell {TD} at (0,265) size 136x20 [r=0 c=0 rs=1 cs=1]
LayoutText {#text} at (0,0) size 35x19
text run at (0,0) width 35: "Body"
LayoutTableRow {TR} at (0,790) size 136x550
LayoutTableCell {TD} at (0,1055) size 136x20 [r=1 c=0 rs=1 cs=1]
LayoutText {#text} at (0,0) size 35x19
text run at (0,0) width 35: "Body"
LayoutTableRow {TR} at (0,1589) size 136x550
LayoutTableCell {TD} at (0,1854) size 136x20 [r=2 c=0 rs=1 cs=1]
LayoutText {#text} at (0,0) size 35x19
text run at (0,0) width 35: "Body"
layer at (0,0) size 800x600 scrollHeight 2361
LayoutView at (0,0) size 1046x799
layer at (0,0) size 1046x2361 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
LayoutBlockFlow {HTML} at (0,0) size 1046x2361
LayoutBlockFlow {BODY} at (8,8) size 1030x2345
LayoutTable {TABLE} at (0,0) size 140x2345
LayoutTableSection {THEAD} at (0,0) size 140x102
LayoutTableRow {TR} at (0,0) size 140x102
LayoutTableCell {TH} at (0,41) size 140x20 [r=0 c=0 rs=1 cs=1]
LayoutText {#text} at (10,1) size 120x18
text run at (10,1) width 120: "First level header"
LayoutTableSection {TBODY} at (0,102) size 140x2243
LayoutTableRow {TR} at (0,0) size 140x2243
LayoutTableCell {TD} at (0,0) size 140x2243 [r=0 c=0 rs=1 cs=1]
LayoutTable {TABLE} at (1,1) size 138x2241
LayoutTableSection {THEAD} at (0,0) size 138x102
LayoutTableRow {TR} at (0,0) size 138x102
LayoutTableCell {TH} at (0,41) size 138x20 [r=0 c=0 rs=1 cs=1]
LayoutText {#text} at (1,1) size 136x18
text run at (1,1) width 136: "Second level header"
LayoutTableSection {TBODY} at (0,102) size 138x2139
LayoutTableRow {TR} at (0,0) size 138x550
LayoutTableCell {TD} at (0,266) size 138x18 [r=0 c=0 rs=1 cs=1]
LayoutText {#text} at (0,0) size 35x18
text run at (0,0) width 35: "Body"
LayoutTableRow {TR} at (0,790) size 138x550
LayoutTableCell {TD} at (0,1056) size 138x18 [r=1 c=0 rs=1 cs=1]
LayoutText {#text} at (0,0) size 35x18
text run at (0,0) width 35: "Body"
LayoutTableRow {TR} at (0,1589) size 138x550
LayoutTableCell {TD} at (0,1855) size 138x18 [r=2 c=0 rs=1 cs=1]
LayoutText {#text} at (0,0) size 35x18
text run at (0,0) width 35: "Body"
layer at (0,0) size 800x600 scrollHeight 2361
LayoutView at (0,0) size 1046x799
layer at (0,0) size 1046x2361 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
LayoutBlockFlow {HTML} at (0,0) size 1046x2361
LayoutBlockFlow {BODY} at (8,8) size 1030x2345
LayoutTable {TABLE} at (0,0) size 138x2345
LayoutTableSection {THEAD} at (0,0) size 138x102
LayoutTableRow {TR} at (0,0) size 138x102
LayoutTableCell {TH} at (0,40) size 138x22 [r=0 c=0 rs=1 cs=1]
LayoutText {#text} at (10,1) size 118x19
text run at (10,1) width 118: "First level header"
LayoutTableSection {TBODY} at (0,102) size 138x2243
LayoutTableRow {TR} at (0,0) size 138x2243
LayoutTableCell {TD} at (0,0) size 138x2243 [r=0 c=0 rs=1 cs=1]
LayoutTable {TABLE} at (1,1) size 136x2241
LayoutTableSection {THEAD} at (0,0) size 136x102
LayoutTableRow {TR} at (0,0) size 136x102
LayoutTableCell {TH} at (0,40) size 136x22 [r=0 c=0 rs=1 cs=1]
LayoutText {#text} at (1,1) size 134x19
text run at (1,1) width 134: "Second level header"
LayoutTableSection {TBODY} at (0,102) size 136x2139
LayoutTableRow {TR} at (0,0) size 136x550
LayoutTableCell {TD} at (0,265) size 136x20 [r=0 c=0 rs=1 cs=1]
LayoutText {#text} at (0,0) size 33x19
text run at (0,0) width 33: "Body"
LayoutTableRow {TR} at (0,790) size 136x550
LayoutTableCell {TD} at (0,1055) size 136x20 [r=1 c=0 rs=1 cs=1]
LayoutText {#text} at (0,0) size 33x19
text run at (0,0) width 33: "Body"
LayoutTableRow {TR} at (0,1589) size 136x550
LayoutTableCell {TD} at (0,1854) size 136x20 [r=2 c=0 rs=1 cs=1]
LayoutText {#text} at (0,0) size 33x19
text run at (0,0) width 33: "Body"
<!DOCTYPE html>
<style>
body {
font-size: 30px;
line-height: 50px;
}
</style>
<script>
if (window.testRunner)
testRunner.setPrinting();
</script>
<table>
<thead>
<tr>
<th>Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr>
<td>5</td>
</tr>
<tr>
<td>6</td>
</tr>
<tr>
<td>7</td>
</tr>
<tr>
<td>8</td>
</tr>
<tr>
<td>9</td>
</tr>
<tr>
<td>10</td>
</tr>
<tr>
<td>11</td>
</tr>
<tr>
<td>12</td>
</tr>
<tr>
<td>13</td>
</tr>
<tr>
<td>14</td>
</tr>
<tr>
<td>15</td>
</tr>
<tr>
<td>16</td>
</tr>
<tr>
<td>17</td>
</tr>
<tr>
<td>18</td>
</tr>
<tr>
<td>19</td>
</tr>
<tr>
<td>20</td>
</tr>
<tr>
<td>21</td>
</tr>
<tr>
<td>22</td>
</tr>
<tr>
<td>23</td>
</tr>
<tr>
<td>24</td>
</tr>
<tr>
<td>25</td>
</tr>
<tr>
<td>26</td>
</tr>
<tr>
<td>27</td>
</tr>
<tr>
<td>28</td>
</tr>
<tr>
<td>29</td>
</tr>
<tr>
<td>30</td>
</tr>
<tr>
<td>31</td>
</tr>
<tr>
<td>32</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Footer</th>
</tr>
</tfoot>
</table>
<!DOCTYPE html>
<style>
body {
font-size: 30px;
line-height: 50px;
}
thead, tfoot {
will-change: transform;
}
</style>
<script>
if (window.testRunner)
testRunner.setPrinting();
</script>
<table>
<thead>
<tr>
<th>Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr>
<td>5</td>
</tr>
<tr>
<td>6</td>
</tr>
<tr>
<td>7</td>
</tr>
<tr>
<td>8</td>
</tr>
<tr>
<td>9</td>
</tr>
<tr>
<td>10</td>
</tr>
<tr>
<td>11</td>
</tr>
<tr>
<td>12</td>
</tr>
<tr>
<td>13</td>
</tr>
<tr>
<td>14</td>
</tr>
<tr>
<td>15</td>
</tr>
<tr>
<td>16</td>
</tr>
<tr>
<td>17</td>
</tr>
<tr>
<td>18</td>
</tr>
<tr>
<td>19</td>
</tr>
<tr>
<td>20</td>
</tr>
<tr>
<td>21</td>
</tr>
<tr>
<td>22</td>
</tr>
<tr>
<td>23</td>
</tr>
<tr>
<td>24</td>
</tr>
<tr>
<td>25</td>
</tr>
<tr>
<td>26</td>
</tr>
<tr>
<td>27</td>
</tr>
<tr>
<td>28</td>
</tr>
<tr>
<td>29</td>
</tr>
<tr>
<td>30</td>
</tr>
<tr>
<td>31</td>
</tr>
<tr>
<td>32</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Footer</th>
</tr>
</tfoot>
</table>
<!DOCTYPE html>
<style>
table { border-spacing: 0; }
th { height: 100px; }
td td { height: 550px; padding: 0; }
</style>
<script>
if (window.testRunner)
testRunner.setPrinting();
</script>
<table>
<thead>
<tr><th>First level header</th></tr>
</thead>
<tr>
<td>
<table>
<thead>
<tr><th>Second level header</th></tr>
</thead>
<tr><td>Body</td></tr>
<tr><td>Body</td></tr>
<tr><td>Body</td></tr>
</table>
</td>
</tr>
</table>
<!DOCTYPE html>
<style>
body { color: rgba(0, 0, 0, 0.4); font-weight: bold; }
table { border-collapse: collapse; }
tr { page-break-inside: avoid; border-left: 5px solid rgba(0, 0, 0, 0.4); }
th { width: 400px; height: 100px; }
td { width: 400px; height: 600px; }
</style>
<script>
if (window.testRunner)
testRunner.setPrinting();
</script>
<div>All text and borders should be in light gray</div>
<table>
<tr><th>Header</th></tr>
<tr><td>Foo</td></tr>
<tr><th>Header</th></tr>
<tr><td>Foo</td></tr>
<tr><th>Header</th></tr>
<tr><td>Foo</td></tr>
<tr><th>Header</th></tr>
<tr><td>Foo</td></tr>
</table>
<div style=>All text and borders should be in light gray</div>
<!DOCTYPE html>
<style>
body { color: rgba(0, 0, 0, 0.4); font-weight: bold; }
table { border-collapse: collapse; }
tr { border-left: 5px solid rgba(0, 0, 0, 0.4); }
th { width: 400px; height: 100px; }
td { width: 400px; height: 600px; }
</style>
<script>
if (window.testRunner)
testRunner.setPrinting();
</script>
<div>All text and borders should be in light gray</div>
<table>
<thead>
<tr><th>Header</th></tr>
</thead>
<tbody>
<tr><td>Foo</td></tr>
<tr><td>Foo</td></tr>
<tr><td>Foo</td></tr>
<tr><td>Foo</td></tr>
</tbody>
</table>
<div style=>All text and borders should be in light gray</div>
<!DOCTYPE html>
<style>
body {
font-size: 30px;
line-height: 50px;
}
table {
border-collapse: collapse;
}
tr {
border-bottom: 1px solid black;
}
</style>
<script>
if (window.testRunner)
testRunner.setPrinting();
</script>
<table>
<thead>
<tr>
<th>Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr>
<td>5</td>
</tr>
<tr>
<td>6</td>
</tr>
<tr>
<td>7</td>
</tr>
<tr>
<td>8</td>
</tr>
<tr>
<td>9</td>
</tr>
<tr>
<td>10</td>
</tr>
<tr>
<td>11</td>
</tr>
<tr>
<td>12</td>
</tr>
<tr>
<td>13</td>
</tr>
<tr>
<td>14</td>
</tr>
<tr>
<td>15</td>
</tr>
<tr>
<td>16</td>
</tr>
<tr>
<td>17</td>
</tr>
<tr>
<td>18</td>
</tr>
<tr>
<td>19</td>
</tr>
<tr>
<td>20</td>
</tr>
<tr>
<td>21</td>
</tr>
<tr>
<td>22</td>
</tr>
<tr>
<td>23</td>
</tr>
<tr>
<td>24</td>
</tr>
<tr>
<td>25</td>
</tr>
<tr>
<td>26</td>
</tr>
<tr>
<td>27</td>
</tr>
<tr>
<td>28</td>
</tr>
<tr>
<td>29</td>
</tr>
<tr>
<td>30</td>
</tr>
<tr>
<td>31</td>
</tr>
<tr>
<td>32</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Footer</th>
</tr>
</tfoot>
</table>
<!DOCTYPE html>
<style>
body {
font-size: 30px;
line-height: 50px;
}
table {
position: relative;
border-collapse: collapse;
}
tr {
border-bottom: 1px solid black;
}
</style>
<script>
if (window.testRunner)
testRunner.setPrinting();
</script>
<table>
<thead>
<tr>
<th>Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
</tr>
<tr>
<td>2</td>
</tr>
<tr>
<td>3</td>
</tr>
<tr>
<td>4</td>
</tr>
<tr>
<td>5</td>
</tr>
<tr>
<td>6</td>
</tr>
<tr>
<td>7</td>
</tr>
<tr>
<td>8</td>
</tr>
<tr>
<td>9</td>
</tr>
<tr>
<td>10</td>
</tr>
<tr>
<td>11</td>
</tr>
<tr>
<td>12</td>
</tr>
<tr>
<td>13</td>
</tr>
<tr>
<td>14</td>
</tr>
<tr>
<td>15</td>
</tr>
<tr>
<td>16</td>
</tr>
<tr>
<td>17</td>
</tr>
<tr>
<td>18</td>
</tr>
<tr>
<td>19</td>
</tr>
<tr>
<td>20</td>
</tr>
<tr>
<td>21</td>
</tr>
<tr>
<td>22</td>
</tr>
<tr>
<td>23</td>
</tr>
<tr>
<td>24</td>
</tr>
<tr>
<td>25</td>
</tr>
<tr>
<td>26</td>
</tr>
<tr>
<td>27</td>
</tr>
<tr>
<td>28</td>
</tr>
<tr>
<td>29</td>
</tr>
<tr>
<td>30</td>
</tr>
<tr>
<td>31</td>
</tr>
<tr>
<td>32</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Footer</th>
</tr>
</tfoot>
</table>
......@@ -153,6 +153,10 @@ struct CORE_EXPORT PaintInfo {
return nullptr;
}
void SetFragmentLogicalTopInFlowThread(LayoutUnit fragment_logical_top) {
fragment_logical_top_in_flow_thread_ = fragment_logical_top;
}
// FIXME: Introduce setters/getters at some point. Requires a lot of changes
// throughout layout/.
GraphicsContext& context;
......
......@@ -2300,34 +2300,6 @@ void PaintPropertyTreeBuilder::
context_.fragments[page - first_page].logical_top_in_flow_thread =
page * page_height;
}
// We should also create fragments for the painting layer so that it will
// initiate painting of the repeating fragments of the table section.
const auto& painting_object = context_.painting_layer->GetLayoutObject();
if (painting_object == object_)
return;
int page_count = ceilf(view->DocumentRect().Height() / page_height);
auto* fragment = &painting_object.GetMutableForPainting().FirstFragment();
// Check if we have created the fragments of the painting layer for another
// repeating table section.
if (fragment->NextFragment()) {
#if DCHECK_IS_ON()
int fragment_count = 1;
while ((fragment = fragment->NextFragment()))
fragment_count++;
DCHECK_EQ(fragment_count, page_count);
#endif
return;
}
for (int page = 1; page < page_count; page++) {
auto* new_fragment = &fragment->EnsureNextFragment();
new_fragment->SetLocalBorderBoxProperties(
fragment->LocalBorderBoxProperties());
new_fragment->SetLogicalTopInFlowThread(page * page_height);
fragment = new_fragment;
}
}
bool PaintPropertyTreeBuilder::IsRepeatingInPagedMedia() const {
......
......@@ -5456,11 +5456,7 @@ TEST_P(PaintPropertyTreeBuilderTest, RepeatingTableSectionInPagedMedia) {
EXPECT_EQ(LayoutPoint(0, 1400), FragmentAt(foot, 2).PaintOffset());
const auto& painting_layer_object = head->PaintingLayer()->GetLayoutObject();
ASSERT_EQ(5u, NumFragments(&painting_layer_object));
for (int i = 0; i < 3; i++) {
const auto& fragment = FragmentAt(&painting_layer_object, i);
EXPECT_EQ(LayoutUnit(i * 400), fragment.LogicalTopInFlowThread());
}
ASSERT_EQ(1u, NumFragments(&painting_layer_object));
GetFrame().EndPrinting();
GetDocument().View()->UpdateAllLifecyclePhases();
......
......@@ -15,6 +15,7 @@
#include "third_party/blink/renderer/core/paint/collapsed_border_painter.h"
#include "third_party/blink/renderer/core/paint/object_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/table_cell_painter.h"
#include "third_party/blink/renderer/core/paint/table_row_painter.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item_cache_skipper.h"
......@@ -171,13 +172,37 @@ void TableSectionPainter::PaintRepeatingFooterGroup(
void TableSectionPainter::Paint(const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
if (!paint_info.FragmentToPaint(layout_table_section_))
return;
// TODO(crbug.com/805514): Paint mask for table section.
if (paint_info.phase == PaintPhase::kMask)
return;
if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
// If the section has multiple fragments, it should repeatedly paint the
// fragments by itself if:
// - It's not a self-painting layer (otherwise PaintLayerPainter should
// initiate painting of the multiple fragments);
// - the table doesn't have multiple fragments (otherwise the table's
// containing painting layer should initiate painting of the fragments).
bool should_paint_fragments_by_itself =
layout_table_section_.FirstFragment().NextFragment() &&
!layout_table_section_.HasSelfPaintingLayer() &&
!layout_table_section_.Table()->FirstFragment().NextFragment();
if (!should_paint_fragments_by_itself) {
PaintSection(paint_info, paint_offset);
return;
}
for (const auto* fragment = &layout_table_section_.FirstFragment();
fragment; fragment = fragment->NextFragment()) {
PaintInfo fragment_paint_info = paint_info;
fragment_paint_info.SetFragmentLogicalTopInFlowThread(
fragment->LogicalTopInFlowThread());
PaintSection(fragment_paint_info, paint_offset);
}
return;
}
PaintSection(paint_info, paint_offset);
LayoutTable* table = layout_table_section_.Table();
if (table->Header() == layout_table_section_) {
......@@ -223,6 +248,32 @@ void TableSectionPainter::PaintSection(const PaintInfo& paint_info,
void TableSectionPainter::PaintCollapsedBorders(
const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
// If the section has multiple fragments, it should repeatedly paint the
// fragments for collapsed borders by itself if the table doesn't have
// multiple fragments (otherwise the table's containing painting layer
// should initiate painting of the fragments). The condition here is
// different from that in Paint() because the table always initiate painting
// of collapsed borders regardless of self-painting status of the section.
bool should_paint_fragments_by_itself =
layout_table_section_.FirstFragment().NextFragment() &&
!layout_table_section_.Table()->FirstFragment().NextFragment();
if (!should_paint_fragments_by_itself) {
PaintCollapsedSectionBorders(paint_info, paint_offset);
return;
}
for (const auto* fragment = &layout_table_section_.FirstFragment();
fragment; fragment = fragment->NextFragment()) {
PaintInfo fragment_paint_info = paint_info;
fragment_paint_info.SetFragmentLogicalTopInFlowThread(
fragment->LogicalTopInFlowThread());
PaintCollapsedSectionBorders(fragment_paint_info, paint_offset);
}
return;
}
PaintCollapsedSectionBorders(paint_info, paint_offset);
LayoutTable* table = layout_table_section_.Table();
if (table->Header() == layout_table_section_) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment