github.com/secoba/wails/v2@v2.6.4/internal/frontend/desktop/windows/winc/font.go (about)

     1  //go:build windows
     2  
     3  /*
     4   * Copyright (C) 2019 The Winc Authors. All Rights Reserved.
     5   * Copyright (C) 2010-2013 Allen Dang. All Rights Reserved.
     6   */
     7  
     8  package winc
     9  
    10  import (
    11  	"syscall"
    12  
    13  	"github.com/secoba/wails/v2/internal/frontend/desktop/windows/winc/w32"
    14  )
    15  
    16  const (
    17  	FontBold      byte = 0x01
    18  	FontItalic    byte = 0x02
    19  	FontUnderline byte = 0x04
    20  	FontStrikeOut byte = 0x08
    21  )
    22  
    23  func init() {
    24  	DefaultFont = NewFont("MS Shell Dlg 2", 8, 0)
    25  }
    26  
    27  type Font struct {
    28  	hfont     w32.HFONT
    29  	family    string
    30  	pointSize int
    31  	style     byte
    32  }
    33  
    34  func NewFont(family string, pointSize int, style byte) *Font {
    35  	if style > FontBold|FontItalic|FontUnderline|FontStrikeOut {
    36  		panic("Invalid font style")
    37  	}
    38  
    39  	//Retrive screen DPI
    40  	hDC := w32.GetDC(0)
    41  	defer w32.ReleaseDC(0, hDC)
    42  	screenDPIY := w32.GetDeviceCaps(hDC, w32.LOGPIXELSY)
    43  
    44  	font := Font{
    45  		family:    family,
    46  		pointSize: pointSize,
    47  		style:     style,
    48  	}
    49  
    50  	font.hfont = font.createForDPI(screenDPIY)
    51  	if font.hfont == 0 {
    52  		panic("CreateFontIndirect failed")
    53  	}
    54  
    55  	return &font
    56  }
    57  
    58  func (fnt *Font) createForDPI(dpi int) w32.HFONT {
    59  	var lf w32.LOGFONT
    60  
    61  	lf.Height = int32(-w32.MulDiv(fnt.pointSize, dpi, 72))
    62  	if fnt.style&FontBold > 0 {
    63  		lf.Weight = w32.FW_BOLD
    64  	} else {
    65  		lf.Weight = w32.FW_NORMAL
    66  	}
    67  	if fnt.style&FontItalic > 0 {
    68  		lf.Italic = 1
    69  	}
    70  	if fnt.style&FontUnderline > 0 {
    71  		lf.Underline = 1
    72  	}
    73  	if fnt.style&FontStrikeOut > 0 {
    74  		lf.StrikeOut = 1
    75  	}
    76  	lf.CharSet = w32.DEFAULT_CHARSET
    77  	lf.OutPrecision = w32.OUT_TT_PRECIS
    78  	lf.ClipPrecision = w32.CLIP_DEFAULT_PRECIS
    79  	lf.Quality = w32.CLEARTYPE_QUALITY
    80  	lf.PitchAndFamily = w32.VARIABLE_PITCH | w32.FF_SWISS
    81  
    82  	src := syscall.StringToUTF16(fnt.family)
    83  	dest := lf.FaceName[:]
    84  	copy(dest, src)
    85  
    86  	return w32.CreateFontIndirect(&lf)
    87  }
    88  
    89  func (fnt *Font) GetHFONT() w32.HFONT {
    90  	return fnt.hfont
    91  }
    92  
    93  func (fnt *Font) Bold() bool {
    94  	return fnt.style&FontBold > 0
    95  }
    96  
    97  func (fnt *Font) Dispose() {
    98  	if fnt.hfont != 0 {
    99  		w32.DeleteObject(w32.HGDIOBJ(fnt.hfont))
   100  	}
   101  }
   102  
   103  func (fnt *Font) Family() string {
   104  	return fnt.family
   105  }
   106  
   107  func (fnt *Font) Italic() bool {
   108  	return fnt.style&FontItalic > 0
   109  }
   110  
   111  func (fnt *Font) StrikeOut() bool {
   112  	return fnt.style&FontStrikeOut > 0
   113  }
   114  
   115  func (fnt *Font) Underline() bool {
   116  	return fnt.style&FontUnderline > 0
   117  }
   118  
   119  func (fnt *Font) Style() byte {
   120  	return fnt.style
   121  }