зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1548612 Part 2 - Fix GetTextWidthHeight for strings with no line breaks. r=agashlin
The current implementation of GetTextWidthHeight attempts to guess how much height a string needs to fit into a given width based on how long the string is when rendered onto one line of unlimited width. This doesn't work because breaking up the string into lines introduces additional space at the end of the lines that the single-line method doesn't account for. This patch replaces all of that logic with asking DrawText to render the string into the width of interest and then just seeing how much height it ended up needing in order to do that. We also take the opportunity to clarify what GetDlgItemBottomDU was doing, because it isn't exactly what it claimed to be doing. Depends on D31139 Differential Revision: https://phabricator.services.mozilla.com/D31140 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
c71e8f6c5f
Коммит
7adf1fa4c3
|
@ -8178,40 +8178,34 @@ end:
|
|||
!macroend
|
||||
|
||||
/**
|
||||
* Gets the number of dialog units from the top of a dialog to the bottom of a
|
||||
* control
|
||||
* Gets the number of pixels from the top of a dialog to the bottom of a control
|
||||
*
|
||||
* _DIALOG the handle of the dialog
|
||||
* _CONTROL the handle of the control
|
||||
* _RES_DU return value - dialog units from the top of the dialog to the bottom
|
||||
* of the control
|
||||
* _RES_PX return value - pixels from the top of the dialog to the bottom
|
||||
* of the control
|
||||
*/
|
||||
!macro GetDlgItemBottomDUCall _DIALOG _CONTROL _RES_DU
|
||||
Push "${_DIALOG}"
|
||||
!macro GetDlgItemBottomPXCall _CONTROL _RES_PX
|
||||
Push "${_CONTROL}"
|
||||
${CallArtificialFunction} GetDlgItemBottomDU_
|
||||
Pop ${_RES_DU}
|
||||
${CallArtificialFunction} GetDlgItemBottomPX_
|
||||
Pop ${_RES_PX}
|
||||
!macroend
|
||||
|
||||
!define GetDlgItemBottomDU "!insertmacro GetDlgItemBottomDUCall"
|
||||
!define un.GetDlgItemBottomDU "!insertmacro GetDlgItemBottomDUCall"
|
||||
!define GetDlgItemBottomPX "!insertmacro GetDlgItemBottomPXCall"
|
||||
!define un.GetDlgItemBottomPX "!insertmacro GetDlgItemBottomPXCall"
|
||||
|
||||
!macro GetDlgItemBottomDU_
|
||||
!macro GetDlgItemBottomPX_
|
||||
Exch $0 ; handle of the control
|
||||
Exch $1 ; handle of the dialog
|
||||
Push $1
|
||||
Push $2
|
||||
Push $3
|
||||
|
||||
; #32770 is the dialog class
|
||||
FindWindow $2 "#32770" "" $HWNDPARENT
|
||||
System::Call '*(i, i, i, i) i .r3'
|
||||
System::Call 'user32::GetWindowRect(i r0, i r3)'
|
||||
System::Call 'user32::MapWindowPoints(i 0, i r2, i r3, i 2)'
|
||||
System::Call 'user32::MapDialogRect(i r1, i r3)'
|
||||
System::Call '*$3(i, i, i, i .r0)'
|
||||
System::Free $3
|
||||
FindWindow $1 "#32770" "" $HWNDPARENT
|
||||
System::Call '*(i, i, i, i) i .r2'
|
||||
System::Call 'user32::GetWindowRect(i r0, i r2)'
|
||||
System::Call 'user32::MapWindowPoints(i 0, i r1, i r2, i 2)'
|
||||
System::Call '*$2(i, i, i, i .r0)'
|
||||
System::Free $2
|
||||
|
||||
Pop $3
|
||||
Pop $2
|
||||
Pop $1
|
||||
Exch $0 ; pixels from the top of the dialog to the bottom of the control
|
||||
|
@ -8219,17 +8213,17 @@ end:
|
|||
|
||||
/**
|
||||
* Gets the width and height for sizing a control that has the specified text.
|
||||
* If the text has embedded newlines then the width and height will be
|
||||
* determined without trying to optimize the control's width and height. If the
|
||||
* text doesn't contain newlines the control's height and width will be
|
||||
* dynamically determined using a minimum of 3 lines (incrementing the
|
||||
* number of lines if necessary) for the height and the maximum width specified.
|
||||
* The control's height and width will be dynamically determined for the maximum
|
||||
* width specified.
|
||||
*
|
||||
* _TEXT the text
|
||||
* _FONT the font to use when getting the width and height
|
||||
* _MAX_WIDTH the maximum width for the control
|
||||
* _RES_WIDTH return value - control width for the text
|
||||
* _RES_HEIGHT return value - control height for the text
|
||||
* _MAX_WIDTH the maximum width for the control in pixels
|
||||
* _RES_WIDTH return value - control width for the text in pixels.
|
||||
* This might be larger than _MAX_WIDTH if that constraint couldn't
|
||||
* be satisfied, e.g. a single word that couldn't be broken up is
|
||||
* longer than _MAX_WIDTH by itself.
|
||||
* _RES_HEIGHT return value - control height for the text in pixels
|
||||
*/
|
||||
!macro GetTextWidthHeight
|
||||
|
||||
|
@ -8245,25 +8239,25 @@ end:
|
|||
!define ${_MOZFUNC_UN}GetTextWidthHeight "!insertmacro ${_MOZFUNC_UN}GetTextWidthHeightCall"
|
||||
|
||||
Function ${_MOZFUNC_UN}GetTextWidthHeight
|
||||
Exch $0 ; maximum width use to calculate the control's width and height
|
||||
Exch 1
|
||||
Exch $1 ; font
|
||||
Exch 2
|
||||
Exch $2 ; text
|
||||
Push $3
|
||||
Push $4
|
||||
Push $5
|
||||
Push $6
|
||||
Push $7
|
||||
Push $8
|
||||
Push $9
|
||||
Push $R0
|
||||
Push $R1
|
||||
Push $R2
|
||||
; Stack contents after each instruction (top of the stack on the left):
|
||||
; _MAX_WIDTH _FONT _TEXT
|
||||
Exch $0 ; $0 _FONT _TEXT
|
||||
Exch 1 ; _FONT $0 _TEXT
|
||||
Exch $1 ; $1 $0 _TEXT
|
||||
Exch 2 ; _TEXT $0 $1
|
||||
Exch $2 ; $2 $0 $1
|
||||
; That's all the parameters, now save our scratch registers.
|
||||
Push $3 ; handle to a temporary control for drawing the text into
|
||||
Push $4 ; DC handle
|
||||
Push $5 ; string length of the text argument
|
||||
Push $6 ; RECT struct to call DrawText with
|
||||
Push $7 ; width returned from DrawText
|
||||
Push $8 ; height returned from DrawText
|
||||
Push $9 ; flags to pass to DrawText
|
||||
|
||||
StrCpy $R2 "${DT_NOCLIP}|${DT_CALCRECT}"
|
||||
StrCpy $9 "${DT_NOCLIP}|${DT_CALCRECT}|${DT_WORDBREAK}"
|
||||
!ifdef ${AB_CD}_rtl
|
||||
StrCpy $R2 "$R2|${DT_RTLREADING}"
|
||||
StrCpy $9 "$9|${DT_RTLREADING}"
|
||||
!endif
|
||||
|
||||
; Reuse the existing NSIS control which is used for BrandingText instead
|
||||
|
@ -8274,56 +8268,18 @@ end:
|
|||
System::Call 'gdi32::SelectObject(i r4, i r1)'
|
||||
|
||||
StrLen $5 "$2" ; text length
|
||||
System::Call '*(i, i, i, i) i .r6'
|
||||
System::Call '*(i, i, i r0, i) i .r6'
|
||||
|
||||
ClearErrors
|
||||
${${_MOZFUNC_UN}WordFind} "$2" "$\n" "E#" $R0
|
||||
${If} ${Errors}
|
||||
; When there aren't newlines in the text calculate the size of the
|
||||
; rectangle needed for the text with a minimum of three lines of text.
|
||||
ClearErrors
|
||||
System::Call 'user32::DrawTextW(i r4, t $\"$2$\", i r5, i r6, \
|
||||
i $R2|${DT_SINGLELINE})'
|
||||
System::Call '*$6(i, i, i .r8, i .r7)'
|
||||
System::Free $6
|
||||
System::Call 'user32::DrawTextW(i r4, t $\"$2$\", i r5, i r6, i r9)'
|
||||
System::Call '*$6(i, i, i .r7, i .r8)'
|
||||
System::Free $6
|
||||
|
||||
; Get the approximate number height needed to display the text starting
|
||||
; with a minimum of 3 lines of text.
|
||||
StrCpy $9 $8
|
||||
StrCpy $R1 2 ; set the number of lines initially to 2
|
||||
${Do}
|
||||
IntOp $R1 $R1 + 1 ; increment the number of lines
|
||||
IntOp $9 $8 / $R1
|
||||
${LoopUntil} $9 < $0
|
||||
IntOp $7 $7 * $R1
|
||||
|
||||
StrCpy $R0 $9
|
||||
${Do}
|
||||
IntOp $R0 $R0 + 20
|
||||
System::Call '*(i, i, i R0, i r7) i .r6'
|
||||
System::Call 'user32::DrawTextW(i r4, t $\"$2$\", i r5, i r6, \
|
||||
i $R2|${DT_WORDBREAK}) i .R1'
|
||||
System::Call '*$6(i, i, i .r8, i .r9)'
|
||||
System::Free $6
|
||||
${LoopUntil} $7 >= $R1
|
||||
${Else}
|
||||
; When there are newlines in the text just return the size of the
|
||||
; rectangle for the text.
|
||||
System::Call 'user32::DrawTextW(i r4, t $\"$2$\", i r5, i r6, i $R2)'
|
||||
System::Call '*$6(i, i, i .r8, i .r9)'
|
||||
System::Free $6
|
||||
${EndIf}
|
||||
|
||||
; Reselect the original DC
|
||||
System::Call 'gdi32::SelectObject(i r4, i r1)'
|
||||
System::Call 'user32::ReleaseDC(i r3, i r4)'
|
||||
|
||||
StrCpy $1 $9
|
||||
StrCpy $0 $8
|
||||
StrCpy $1 $8
|
||||
StrCpy $0 $7
|
||||
|
||||
Pop $R2
|
||||
Pop $R1
|
||||
Pop $R0
|
||||
; Restore the values that were in our scratch registers.
|
||||
Pop $9
|
||||
Pop $8
|
||||
Pop $7
|
||||
|
@ -8331,11 +8287,14 @@ end:
|
|||
Pop $5
|
||||
Pop $4
|
||||
Pop $3
|
||||
Exch $2
|
||||
Exch 2
|
||||
Exch $1 ; return height
|
||||
Exch 1
|
||||
Exch $0 ; return width
|
||||
; Restore our parameter registers and return our results.
|
||||
; Stack contents after each instruction (top of the stack on the left):
|
||||
; $2 $0 $1
|
||||
Pop $2 ; $0 $1
|
||||
Exch 1 ; $1 $0
|
||||
Exch $1 ; _RES_HEIGHT $0
|
||||
Exch 1 ; $0 _RES_HEIGHT
|
||||
Exch $0 ; _RES_WIDTH _RES_HEIGHT
|
||||
FunctionEnd
|
||||
|
||||
!verbose pop
|
||||
|
|
Загрузка…
Ссылка в новой задаче