1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "xfa/fxfa/cxfa_fwltheme.h" 8 9 #include "core/fxcrt/fx_codepage.h" 10 #include "xfa/fde/cfde_textout.h" 11 #include "xfa/fgas/font/cfgas_gefont.h" 12 #include "xfa/fwl/cfwl_barcode.h" 13 #include "xfa/fwl/cfwl_caret.h" 14 #include "xfa/fwl/cfwl_checkbox.h" 15 #include "xfa/fwl/cfwl_combobox.h" 16 #include "xfa/fwl/cfwl_datetimepicker.h" 17 #include "xfa/fwl/cfwl_edit.h" 18 #include "xfa/fwl/cfwl_listbox.h" 19 #include "xfa/fwl/cfwl_monthcalendar.h" 20 #include "xfa/fwl/cfwl_picturebox.h" 21 #include "xfa/fwl/cfwl_pushbutton.h" 22 #include "xfa/fwl/cfwl_scrollbar.h" 23 #include "xfa/fwl/cfwl_themebackground.h" 24 #include "xfa/fwl/cfwl_themetext.h" 25 #include "xfa/fxfa/cxfa_ffapp.h" 26 #include "xfa/fxfa/cxfa_ffwidget.h" 27 #include "xfa/fxfa/parser/cxfa_para.h" 28 #include "xfa/fxgraphics/cxfa_gecolor.h" 29 30 namespace { 31 32 const wchar_t* const g_FWLTheme_CalFonts[] = { 33 L"Arial", L"Courier New", L"DejaVu Sans", 34 }; 35 36 const float kLineHeight = 12.0f; 37 38 } // namespace 39 40 CXFA_FFWidget* XFA_ThemeGetOuterWidget(CFWL_Widget* pWidget) { 41 CFWL_Widget* pOuter = pWidget; 42 while (pOuter && pOuter->GetOuter()) 43 pOuter = pOuter->GetOuter(); 44 return pOuter ? pOuter->GetLayoutItem() : nullptr; 45 } 46 47 CXFA_FWLTheme::CXFA_FWLTheme(CXFA_FFApp* pApp) 48 : m_pCheckBoxTP(pdfium::MakeUnique<CFWL_CheckBoxTP>()), 49 m_pListBoxTP(pdfium::MakeUnique<CFWL_ListBoxTP>()), 50 m_pPictureBoxTP(pdfium::MakeUnique<CFWL_PictureBoxTP>()), 51 m_pSrollBarTP(pdfium::MakeUnique<CFWL_ScrollBarTP>()), 52 m_pEditTP(pdfium::MakeUnique<CFWL_EditTP>()), 53 m_pComboBoxTP(pdfium::MakeUnique<CFWL_ComboBoxTP>()), 54 m_pMonthCalendarTP(pdfium::MakeUnique<CFWL_MonthCalendarTP>()), 55 m_pDateTimePickerTP(pdfium::MakeUnique<CFWL_DateTimePickerTP>()), 56 m_pPushButtonTP(pdfium::MakeUnique<CFWL_PushButtonTP>()), 57 m_pCaretTP(pdfium::MakeUnique<CFWL_CaretTP>()), 58 m_pBarcodeTP(pdfium::MakeUnique<CFWL_BarcodeTP>()), 59 m_pTextOut(pdfium::MakeUnique<CFDE_TextOut>()), 60 m_pCalendarFont(nullptr), 61 m_pApp(pApp) { 62 m_Rect.Reset(); 63 64 for (size_t i = 0; !m_pCalendarFont && i < FX_ArraySize(g_FWLTheme_CalFonts); 65 ++i) { 66 m_pCalendarFont = CFGAS_GEFont::LoadFont(g_FWLTheme_CalFonts[i], 0, 0, 67 m_pApp->GetFDEFontMgr()); 68 } 69 if (!m_pCalendarFont) { 70 m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetFontByCodePage( 71 FX_CODEPAGE_MSWin_WesternEuropean, 0, nullptr); 72 } 73 74 ASSERT(m_pCalendarFont); 75 } 76 77 CXFA_FWLTheme::~CXFA_FWLTheme() { 78 m_pTextOut.reset(); 79 FWLTHEME_Release(); 80 } 81 82 void CXFA_FWLTheme::DrawBackground(CFWL_ThemeBackground* pParams) { 83 GetTheme(pParams->m_pWidget)->DrawBackground(pParams); 84 } 85 86 void CXFA_FWLTheme::DrawText(CFWL_ThemeText* pParams) { 87 if (pParams->m_wsText.IsEmpty()) 88 return; 89 90 if (pParams->m_pWidget->GetClassID() == FWL_Type::MonthCalendar) { 91 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); 92 if (!pWidget) 93 return; 94 95 m_pTextOut->SetStyles(pParams->m_dwTTOStyles); 96 m_pTextOut->SetAlignment(pParams->m_iTTOAlign); 97 m_pTextOut->SetFont(m_pCalendarFont); 98 m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize); 99 m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor); 100 if ((pParams->m_iPart == CFWL_Part::DatesIn) && 101 !(pParams->m_dwStates & FWL_ITEMSTATE_MCD_Flag) && 102 (pParams->m_dwStates & 103 (CFWL_PartState_Hovered | CFWL_PartState_Selected))) { 104 m_pTextOut->SetTextColor(0xFFFFFFFF); 105 } 106 if (pParams->m_iPart == CFWL_Part::Caption) 107 m_pTextOut->SetTextColor(ArgbEncode(0xff, 0, 153, 255)); 108 109 CXFA_Graphics* pGraphics = pParams->m_pGraphics; 110 CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice(); 111 if (!pRenderDevice) 112 return; 113 114 CFX_Matrix mtPart = pParams->m_matrix; 115 const CFX_Matrix* pMatrix = pGraphics->GetMatrix(); 116 if (pMatrix) 117 mtPart.Concat(*pMatrix); 118 119 m_pTextOut->SetMatrix(mtPart); 120 m_pTextOut->DrawLogicText(pRenderDevice, pParams->m_wsText.AsStringView(), 121 pParams->m_rtPart); 122 return; 123 } 124 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); 125 if (!pWidget) 126 return; 127 128 CXFA_Node* pNode = pWidget->GetNode(); 129 CXFA_Graphics* pGraphics = pParams->m_pGraphics; 130 CFX_RenderDevice* pRenderDevice = pGraphics->GetRenderDevice(); 131 if (!pRenderDevice) 132 return; 133 134 m_pTextOut->SetStyles(pParams->m_dwTTOStyles); 135 m_pTextOut->SetAlignment(pParams->m_iTTOAlign); 136 m_pTextOut->SetFont(pNode->GetWidgetAcc()->GetFDEFont(pWidget->GetDoc())); 137 m_pTextOut->SetFontSize(pNode->GetFontSize()); 138 m_pTextOut->SetTextColor(pNode->GetTextColor()); 139 CFX_Matrix mtPart = pParams->m_matrix; 140 const CFX_Matrix* pMatrix = pGraphics->GetMatrix(); 141 if (pMatrix) 142 mtPart.Concat(*pMatrix); 143 144 m_pTextOut->SetMatrix(mtPart); 145 m_pTextOut->DrawLogicText(pRenderDevice, pParams->m_wsText.AsStringView(), 146 pParams->m_rtPart); 147 } 148 149 CFX_RectF CXFA_FWLTheme::GetUIMargin(CFWL_ThemePart* pThemePart) const { 150 CFX_RectF rect; 151 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget); 152 if (!pWidget) 153 return rect; 154 155 CXFA_LayoutItem* pItem = pWidget; 156 CXFA_WidgetAcc* pWidgetAcc = pWidget->GetNode()->GetWidgetAcc(); 157 rect = pWidgetAcc->GetUIMargin(); 158 CXFA_Para* para = pWidgetAcc->GetNode()->GetParaIfExists(); 159 if (para) { 160 rect.left += para->GetMarginLeft(); 161 if (pWidgetAcc->IsMultiLine()) 162 rect.width += para->GetMarginRight(); 163 } 164 if (!pItem->GetPrev()) { 165 if (pItem->GetNext()) 166 rect.height = 0; 167 } else if (!pItem->GetNext()) { 168 rect.top = 0; 169 } else { 170 rect.top = 0; 171 rect.height = 0; 172 } 173 return rect; 174 } 175 176 float CXFA_FWLTheme::GetCXBorderSize() const { 177 return 1.0f; 178 } 179 180 float CXFA_FWLTheme::GetCYBorderSize() const { 181 return 1.0f; 182 } 183 184 float CXFA_FWLTheme::GetFontSize(CFWL_ThemePart* pThemePart) const { 185 if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) 186 return pWidget->GetNode()->GetFontSize(); 187 return FWLTHEME_CAPACITY_FontSize; 188 } 189 190 RetainPtr<CFGAS_GEFont> CXFA_FWLTheme::GetFont( 191 CFWL_ThemePart* pThemePart) const { 192 if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) 193 return pWidget->GetNode()->GetWidgetAcc()->GetFDEFont(pWidget->GetDoc()); 194 return GetTheme(pThemePart->m_pWidget)->GetFont(); 195 } 196 197 float CXFA_FWLTheme::GetLineHeight(CFWL_ThemePart* pThemePart) const { 198 if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) 199 return pWidget->GetNode()->GetLineHeight(); 200 return kLineHeight; 201 } 202 203 float CXFA_FWLTheme::GetScrollBarWidth() const { 204 return 9.0f; 205 } 206 207 FX_COLORREF CXFA_FWLTheme::GetTextColor(CFWL_ThemePart* pThemePart) const { 208 if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) 209 return pWidget->GetNode()->GetTextColor(); 210 return FWLTHEME_CAPACITY_TextColor; 211 } 212 213 CFX_SizeF CXFA_FWLTheme::GetSpaceAboveBelow(CFWL_ThemePart* pThemePart) const { 214 CFX_SizeF sizeAboveBelow; 215 if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) { 216 CXFA_Para* para = pWidget->GetNode()->GetParaIfExists(); 217 if (para) { 218 sizeAboveBelow.width = para->GetSpaceAbove(); 219 sizeAboveBelow.height = para->GetSpaceBelow(); 220 } 221 } 222 return sizeAboveBelow; 223 } 224 225 void CXFA_FWLTheme::CalcTextRect(CFWL_ThemeText* pParams, CFX_RectF& rect) { 226 if (pParams->m_pWidget->GetClassID() == FWL_Type::MonthCalendar) { 227 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); 228 if (!pWidget || !pParams || !m_pTextOut) 229 return; 230 231 m_pTextOut->SetFont(m_pCalendarFont); 232 m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize); 233 m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor); 234 m_pTextOut->SetAlignment(pParams->m_iTTOAlign); 235 m_pTextOut->SetStyles(pParams->m_dwTTOStyles); 236 m_pTextOut->CalcLogicSize(pParams->m_wsText, rect); 237 } 238 239 CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget); 240 if (!pWidget) 241 return; 242 243 CXFA_Node* pNode = pWidget->GetNode(); 244 m_pTextOut->SetFont(pNode->GetWidgetAcc()->GetFDEFont(pWidget->GetDoc())); 245 m_pTextOut->SetFontSize(pNode->GetFontSize()); 246 m_pTextOut->SetTextColor(pNode->GetTextColor()); 247 if (!pParams) 248 return; 249 250 m_pTextOut->SetAlignment(pParams->m_iTTOAlign); 251 m_pTextOut->SetStyles(pParams->m_dwTTOStyles); 252 m_pTextOut->CalcLogicSize(pParams->m_wsText, rect); 253 } 254 255 CFWL_WidgetTP* CXFA_FWLTheme::GetTheme(CFWL_Widget* pWidget) const { 256 switch (pWidget->GetClassID()) { 257 case FWL_Type::CheckBox: 258 return m_pCheckBoxTP.get(); 259 case FWL_Type::ListBox: 260 return m_pListBoxTP.get(); 261 case FWL_Type::PictureBox: 262 return m_pPictureBoxTP.get(); 263 case FWL_Type::ScrollBar: 264 return m_pSrollBarTP.get(); 265 case FWL_Type::Edit: 266 return m_pEditTP.get(); 267 case FWL_Type::ComboBox: 268 return m_pComboBoxTP.get(); 269 case FWL_Type::MonthCalendar: 270 return m_pMonthCalendarTP.get(); 271 case FWL_Type::DateTimePicker: 272 return m_pDateTimePickerTP.get(); 273 case FWL_Type::PushButton: 274 return m_pPushButtonTP.get(); 275 case FWL_Type::Caret: 276 return m_pCaretTP.get(); 277 case FWL_Type::Barcode: 278 return m_pBarcodeTP.get(); 279 default: 280 return nullptr; 281 } 282 } 283