@@ -329,7 +329,7 @@ void CandidateWindow::HandleMouseEvent(UINT nFlags, const CPoint& point,
329329 const commands::CandidateWindow::Candidate& candidate =
330330 candidate_window_->candidate (i);
331331
332- const CRect rect = ToCRect (table_layout_->GetRowRect (i));
332+ const CRect rect = ToCRect (FlipIfUpsideDown ( table_layout_->GetRowRect (i) ));
333333 if (rect.PtInRect (point)) {
334334 commands::SessionCommand command;
335335 if (close_candidatewindow) {
@@ -636,7 +636,8 @@ Rect CandidateWindow::GetSelectionRectInScreenCord() const {
636636 focused_array_index < candidate_window_->candidate_size ()) {
637637 (void )candidate_window_->candidate (focused_array_index);
638638
639- CRect rect = ToCRect (table_layout_->GetRowRect (focused_array_index));
639+ CRect rect = ToCRect (
640+ FlipIfUpsideDown (table_layout_->GetRowRect (focused_array_index)));
640641 ClientToScreen (&rect);
641642 return Rect (rect.left , rect.top , rect.Width (), rect.Height ());
642643 }
@@ -654,7 +655,27 @@ Rect CandidateWindow::GetFirstRowInClientCord() const {
654655 DCHECK (table_layout_->IsLayoutFrozen ()) << " Table layout is not frozen." ;
655656 DCHECK_GT (table_layout_->number_of_rows (), 0 )
656657 << " number of rows should be positive" ;
657- return table_layout_->GetRowRect (0 );
658+ return FlipIfUpsideDown (table_layout_->GetRowRect (0 ));
659+ }
660+
661+ void CandidateWindow::SetUpsideDown (bool upside_down) {
662+ if (upside_down_ == upside_down) {
663+ return ;
664+ }
665+ upside_down_ = upside_down;
666+ if (m_hWnd != nullptr ) {
667+ Invalidate ();
668+ }
669+ }
670+
671+ Rect CandidateWindow::FlipIfUpsideDown (Rect rect) const {
672+ if (!upside_down_) {
673+ return rect;
674+ }
675+ // Mirror vertically within the window so that the first row comes to the
676+ // bottom and the footer comes to the top.
677+ rect.origin .y = table_layout_->GetTotalSize ().height - rect.Bottom ();
678+ return rect;
658679}
659680
660681void CandidateWindow::DrawCells (HDC dc) {
@@ -676,15 +697,17 @@ void CandidateWindow::DrawCells(HDC dc) {
676697 candidate_window_->candidate (i);
677698 const std::wstring display_string =
678699 GetDisplayStringByColumn (candidate, column_type);
679- const Rect text_rect = table_layout_->GetCellRect (i, column_type);
700+ const Rect text_rect =
701+ FlipIfUpsideDown (table_layout_->GetCellRect (i, column_type));
680702 display_list.push_back (TextRenderingInfo (display_string, text_rect));
681703 }
682704 text_renderer_->RenderTextList (dc, display_list, font_type);
683705 }
684706}
685707
686708void CandidateWindow::DrawVScrollBar (HDC dc) {
687- const Rect& vscroll_rect = table_layout_->GetVScrollBarRect ();
709+ const Rect vscroll_rect =
710+ FlipIfUpsideDown (table_layout_->GetVScrollBarRect ());
688711
689712 if (!vscroll_rect.IsRectEmpty () && candidate_window_->candidate_size () > 0 ) {
690713 const int begin_index = candidate_window_->candidate (0 ).index ();
@@ -697,8 +720,9 @@ void CandidateWindow::DrawVScrollBar(HDC dc) {
697720 FillSolidRect (dc, &background_crect,
698721 ToColorRef (style_.scrollbar_background_color ()));
699722
700- const mozc::Rect& indicator_rect = table_layout_->GetVScrollIndicatorRect (
701- begin_index, end_index, candidates_total);
723+ const mozc::Rect indicator_rect =
724+ FlipIfUpsideDown (table_layout_->GetVScrollIndicatorRect (
725+ begin_index, end_index, candidates_total));
702726
703727 const CRect indicator_crect = ToCRect (indicator_rect);
704728 FillSolidRect (dc, &indicator_crect,
@@ -708,7 +732,8 @@ void CandidateWindow::DrawVScrollBar(HDC dc) {
708732
709733void CandidateWindow::DrawShortcutBackground (HDC dc) {
710734 if (table_layout_->number_of_columns () > 0 ) {
711- Rect shortcut_colmun_rect = table_layout_->GetColumnRect (0 );
735+ Rect shortcut_colmun_rect =
736+ FlipIfUpsideDown (table_layout_->GetColumnRect (0 ));
712737 if (!shortcut_colmun_rect.IsRectEmpty ()) {
713738 // Due to the mismatch of the implementation of the TableLayout class
714739 // and the design requiement, we have to *fix* the width and origin
@@ -727,27 +752,32 @@ void CandidateWindow::DrawShortcutBackground(HDC dc) {
727752}
728753
729754void CandidateWindow::DrawFooter (HDC dc) {
730- const Rect& footer_rect = table_layout_->GetFooterRect ();
755+ const Rect footer_rect = FlipIfUpsideDown ( table_layout_->GetFooterRect () );
731756 if (!candidate_window_->has_footer () || footer_rect.IsRectEmpty ()) {
732757 return ;
733758 }
734759
735760 const int footer_separator_height = style_.footer_border_colors_size ();
736761
737762 // DC pen is available in Windows 2000 and later.
763+ // The separator faces the rows: at the top of the footer normally, and at
764+ // the bottom of the footer when the window is upside down.
738765 {
739766 wil::unique_select_object prev_pen =
740767 wil::SelectObject (dc, static_cast <HPEN >(::GetStockObject (DC_PEN )));
741- for (size_t i = 0 , y = footer_rect.Top (); i < footer_separator_height;
742- y++, i++) {
768+ for (int i = 0 ; i < footer_separator_height; ++i) {
769+ const int y =
770+ upside_down_ ? footer_rect.Bottom () - 1 - i : footer_rect.Top () + i;
743771 ::SetDCPenColor (dc, ToColorRef(style_.footer_border_colors(i)));
744772 ::MoveToEx (dc, footer_rect.Left(), y, nullptr);
745773 ::LineTo (dc, footer_rect.Right(), y);
746774 }
747775 }
748776
749777 const Rect footer_content_rect (
750- footer_rect.Left (), footer_rect.Top () + footer_separator_height,
778+ footer_rect.Left (),
779+ upside_down_ ? footer_rect.Top ()
780+ : footer_rect.Top () + footer_separator_height,
751781 footer_rect.Width (), footer_rect.Height () - footer_separator_height);
752782
753783 // Draw gradient rect in the footer area
@@ -843,8 +873,8 @@ void CandidateWindow::DrawSelectedRect(HDC dc) {
843873 focused_array_index < candidate_window_->candidate_size ()) {
844874 (void )candidate_window_->candidate (focused_array_index);
845875
846- const CRect selected_rect =
847- ToCRect (table_layout_->GetRowRect (focused_array_index));
876+ const CRect selected_rect = ToCRect (
877+ FlipIfUpsideDown (table_layout_->GetRowRect (focused_array_index) ));
848878 FillSolidRect (dc, &selected_rect,
849879 ToColorRef (style_.focused_background_color ()));
850880
@@ -859,7 +889,7 @@ void CandidateWindow::DrawInformationIcon(HDC dc) {
859889 const double scale_factor = GetDPIScalingFactor (dpi_);
860890 for (size_t i = 0 ; i < candidate_window_->candidate_size (); ++i) {
861891 if (candidate_window_->candidate (i).has_information_id ()) {
862- CRect rect = ToCRect (table_layout_->GetRowRect (i));
892+ CRect rect = ToCRect (FlipIfUpsideDown ( table_layout_->GetRowRect (i) ));
863893 rect.left = rect.right - (6.0 * scale_factor);
864894 rect.right = rect.right - (2.0 * scale_factor);
865895 rect.top += (2.0 * scale_factor);
0 commit comments