News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Iczelion's Tutorial 35

Started by Robert Collins, December 27, 2004, 06:09:28 AM

Previous topic - Next topic

Robert Collins

This tutorial shows how to use the Rich Edit DLL to design an Edit window that high lights predetermined keywords. It is an excellant example and I want to use it (or portions of it) to build my own editor but the one thing I dont like is the font associated with the Edit window. Can anyone here post something on how to change the font to say something like Fixedsys at 9 points. I like this font better because it is not a true type font and I like characters to align up on the text lines.   

Ramon Sala

Hi Robert,

You first have to create a font with the specified characteristics (API function CreateFont) and then you send a WM_SETFONT message to the rich edit control.

Ramon
Greetings from Catalonia

pbrennick

Robert,
Courier might be a more visually appealing font than fixedsys and will do what you want.  The secret is to select a nonproportional font which both of them are.  I use Courier as the default in my editor because I like things to line up also.


inv             equ invoke
FontName        DB  'Courier', 25 Dup (0)   ; 32 bytes max (including ASCIIZ terminator)
FontHeight      DD  - 13                ; -12=9pt., -13=10pt., -15=11pt., etc.
FontWeight      DD  400                 ; 400=normal, 700=bold
PointSize       DD  100                 ; PointSize*10, actually


and it is created in this manner...

;         Create font
          inv  lstrcpy, Offset lfnt.lfFaceName, Offset FontName ; Get fontname
          Mov  Eax, FontHeight          ; Get font height
          Mov  lfnt.lfHeight, Eax       ; Store the font height in the logfont structure
          Mov  Eax, FontWeight          ; Get font weight
          Mov  lfnt.lfWeight, Eax       ; Store the font weight in the logfont structure
          inv  CreateFontIndirect, Offset lfnt  ; Create the font
          Mov  hFont, Eax               ; Store it
          inv  SetFormat, hREd


Instead of WM_SETFONT I chose to use the following so I could set tabstops, etc.:

SetFormat Proc hWin:DWord
;---------------------------------------;
        Local chrg1:CHARRANGE         ; Structure
        Local chrg2:CHARRANGE         ; Structure
        Local pf:PARAFORMAT2          ; Structure
        Local cf:CHARFORMAT           ; Structure
        Local tp:DWord                ; Scratch variable
        Local buffer[16]:Byte         ; Temporary buffer
        Local pt:POINT                ; Pixel point
        Local hDC:HDC                 ; Device context
;
;       Save modification state
        inv  SendMessage, hWin, EM_GETMODIFY, 0, 0  ; Get document state
        Push Eax                        ; Save it
;       Save selection
        inv  SendMessage, hWin, EM_EXGETSEL, 0, Addr chrg1  ; Get range of possible selection
        inv  SendMessage, hWin, EM_HIDESELECTION, TRUE, 0   ; Save it by hiding it
;       Select all text
        Mov chrg2.cpMin, 0             ; Get start of document
        Mov chrg2.cpMax, -1            ; Get end of document
        inv  SendMessage, hWin, EM_EXSETSEL, 0, Addr chrg2  ; Select all of the text in the control
;       Set font charset
        Mov cf.cbSize, SizeOf cf       ; Get size of the structure
        Mov cf.dwMask, CFM_CHARSET Or CFM_FACE Or CFM_SIZE Or CFM_COLOR    ; Set the attribute mask
        Mov Al, lfnt.lfCharSet         ; Get current character set
        Mov cf.bCharSet, Al            ; Store it in the structure
        Mov Al, lfnt.lfPitchAndFamily  ; Get character styles
        Mov cf.bPitchAndFamily, Al     ; Store it in the structure

        inv  lstrcpyn, Addr cf.szFaceName, Offset lfnt.lfFaceName, LF_FACESIZE
        Mov Eax, lfnt.lfHeight         ; Get height
        Neg Eax                        ; Multiply by -1
        Mov Ecx, 15                    ; Get multiplier
        Mul Ecx                        ; Multiply by 15
        Mov cf.yHeight, Eax            ; Save the result
        Mov Eax, rgb                   ; Get foreground color
        Mov cf.crTextColor, Eax        ; Save it
        inv  SendMessage, hWin, EM_SETCHARFORMAT, SCF_SELECTION, Addr cf    ; Set character format
;       Get tab width
        inv  GetDC, hWin                ; Retrieves a handle of a device context (DC) for the edit control
        Mov hDC, Eax                   ; Save the DC
        inv  SelectObject, hDC, hFont   ; Selects an object into the specified device context
        Push Eax                        ; Save it
        Mov Eax, 'WWWW'                ; Get 4 of the largest character in the set
        Mov DWord Ptr buffer, Eax      ; Put it in the buffer
        inv  GetTextExtentPoint32, hDC, Addr buffer, 4, Addr pt ; Computes the width and height of the specified string of text
        Pop Eax                        ; Restore the font
        inv  SelectObject, hDC, Eax     ; Reset the device context
        inv  ReleaseDC, hWin, hDC       ; Release the device context resources
        Mov Eax, pt.x                  ; Save the x coordinate (size)
        Mov Ecx, TabSize               ; Get current tabsize
        Mul Ecx                        ; Get pixel value
        Mov Ecx, 15                    ; Get multiplier
        Mul Ecx                        ; Multiply by 15
        Shr Eax, 2                     ; Divide by 2
        Mov tp, Eax                    ; Save the resulting tab points (in pixels)
;       Set tab stops
        Mov pf.cbSize, SizeOf pf       ; Get size of the structure
        Mov pf.dwMask, PFM_TABSTOPS    ; Set mask
        Mov pf.cTabCount, MAX_TAB_STOPS    ; Set tab count
        Xor Eax, Eax                   ; Clear the accumulator
        Xor Edx, Edx                   ; Clear the data register
        Mov Ecx, MAX_TAB_STOPS         ; Get tab count
J001:   Add Eax, tp                    ; Plus pixel count
        Mov DWord Ptr pf.rgxTabs[Edx], Eax ; Store tab stop in the structure
        Add Edx, 4                     ; Get next tab stop
        Loop J001                       ; Build complete tab stop table
        inv  SendMessage, hWin, EM_SETPARAFORMAT, 0, Addr pf    ; Store this information in the edit control
;       Restore modify state
        Pop Eax                        ; Restore the document state
        inv  SendMessage, hWin, EM_SETMODIFY, Eax, 0    ; Reset the edit control to how it was originally
;       Restore selection
        inv  SendMessage, hWin, EM_EXSETSEL, 0, Addr chrg1  ; Get positions of any text that was selected
        inv  SendMessage, hWin, EM_HIDESELECTION, FALSE, 0  ; Make it visible
        Ret                             ; Return
;---------------------------------------;
SetFormat EndP


I hope you find this useful.

Paul

Robert Collins

pbrennick,

Yes, I like Courier also. I picked Fixedsys only because it is what Notepad uses and I kind of like the darkness of the font and Courier is a light weight font. Either one is OK, though.

Ok, I understand the data; FontName, FontHeight, FontWeight, and PointSize and the code.  What I am not understanding is where do you get the lfnt.????? stuff? Like lfnt.lfFaceName and all the others. Also, I get undefined on 'hREd', 'rgb' and 'TabSize'

pbrennick

Robert,
Here are the missing pieces, sorry, I grabbed it out of my editor program.


TabSize         DD      ?               ; Store tabsize (will be set to 4)
hFont           DD      ?               ; Handle for the font goes here
hREd            HWND    ?               ; Handle of the edit control goes here

lfnt    LOGFONT         <>              ; For CreateFontIndirect

If yoiu have any more questions, just ask,
Paul

pbrennick

Robert,
I downloaded the tutorial and took a peek at it.  If you are following his methods, then change all occurences of hREd tohRichEdit and delete the hREd declaration.  That will make sue it all works.
Paul

raymond

Paul,

You seem familiar with RichEdit controls. Would you know how to print the WYSIWYG content of such controls. I can't find any decent tutorial on that subject and the Win32 Programmer's Reference is far from enlightning.

Raymond
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

donkey

Hi Raymond,

I grabbed this from NaN, it is what I use a reference when I need to print something...

Do_Print PROC hWnd:DWORD, wParam:DWORD, lParam:DWORD
LOCAL memdc :DWORD
LOCAL hbmp :DWORD
LOCAL bmp :BITMAP

; Initialize the Print Dialog
; --===============================================
mov yP, 0 ; Start of page..

jmp @F
FontMS        db "MS Sans Serif",0
@@:

; Initialize the Print Dialog
; --===============================================
mov PD.lStructSize, SIZEOF PD
mov eax,hWnd
mov PD.hwndOwner, eax
mov eax,hInstance
mov PD.hInstance, eax
mov PD.Flags, PD_RETURNDC                  ; Return Users DC choices

; Show the Print Dialog Box!
; --===============================================
invoke PrintDlg, offset PD
cmp eax, FALSE
je Done

; IF you specify the PD_RETURNDC value in the Flags member of the PRINTDLG structure and the user
; selects Print To File from the Print dialog box, you can use the DC returned in the hDC member
; of the structure to generate output, but only after you prepare the file for output by specifying
; the name of the file in the lpszOutput member of the DOCINFO structure and calling the StartDoc function.

; Check Get the Printed X+Y extence..
; --===============================================
invoke GetDeviceCaps, PD.hDC, HORZRES
shr eax, 1
mov COLUMN_2, eax                                    ; 2 columns per page
invoke GetDeviceCaps, PD.hDC, VERTRES
shr eax, 6
mov LINE_WIDTH, eax                                  ; 64 Lines / page
mov eax,LINE_WIDTH
mov COLUMN_1,eax

; Create A Printer Font..
; --===============================================
invoke lstrcpy, addr LF.lfFaceName, addr FontMS
mov eax,LINE_WIDTH
mov LF.lfHeight,eax
mov LF.lfWeight, 600
invoke CreateFontIndirect, ADDR LF
mov pFont, eax

; Set up the Document Info Structure
; --===============================================
mov DOC.cbSize, SIZEOF DOC
mov DOC.lpszDocName, offset DocTitle
mov DOC.lpszOutput, NULL
mov DOC.fwType, NULL

; Start the Doc..
; Ensures proper print order of pages..
; --===============================================
invoke StartDoc, PD.hDC, offset DOC

; Start the Page..
; Prepares the printer driver to accept data.
; --===============================================
invoke StartPage, PD.hDC

; Load a Printer Font..
; --===============================================
invoke SelectObject, PD.hDC, pFont

; Print the lines here
; --===============================================
jmp @F
; This is an example
  szTestMessage db "This is a test",0
  szTestMessage2 db "This is a test2",0
@@:

LinePrint OFFSET szTestMessage
LinePrint OFFSET szTestMessage2

invoke CreateCompatibleDC,PD.hDC
mov memdc,eax
invoke LoadBitmap,hInstance,10000
mov hbmp,eax
invoke SelectObject,memdc,hbmp
push eax
invoke GetObject,hbmp,SIZEOF bmp,ADDR bmp

invoke BitBlt,PD.hDC,0,0,bmp.bmWidth,bmp.bmHeight,memdc,0,0,SRCCOPY

pop eax
invoke SelectObject,memdc,eax
invoke DeleteDC,memdc
invoke DeleteObject,hbmp

; Do the End of Page (feed out the paper)
; --===============================================
invoke EndPage, PD.hDC
invoke EndDoc, PD.hDC
invoke DeleteDC, PD.hDC

Done:
ret
Do_Print ENDP
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Manos

Don't forget to destroy the Font that
you create after finish with that.

Manos.

farrier

Repost?

I just implimented printing in an app I've written.  In the app, reports are generated in Rich Text Format (RTF), and Printed without user interaction, Viewed with option to print, View with only option to close.

RTF was used to enabled viewing and printing outside of my app, and to allow emailing the reports.

I originally used WordPad to view and print, but with a report of 2 or more pages, the page breaks (\page) were not handled.  I then used a different editor--Jarte--which worked great, but I sometimes had difficulty automated the file open/print operation.

I then tried the RichEdit control, but the page break was still not handled, and on different printers, page feeds would happen at different places.

Then using Chib777's code from the Print/Preview function released for Hutch--'s QEditor, I was able to "Roll my own"  Now I can simulate page breaks, print in portrait or landscape, collate.  The only thing I haven't figured is how to start printing the last page first.

If there is any interest, I'll post some code and explaination.  Just give me 1 or 2 days, I have a deadline looming! :eek  <- too much coffee!

farrier
It is a GOOD day to code!
Some assembly required!
ASM me!
With every mistake, we must surely be learning. (George...Bush)

pbrennick

farrier,
Any time you post code to this forum, you improve on the usefulness of this forum.  :U

Paul

pbrennick

Robert,
Manos reminds me of something I forgot to tell you.  Make sure you add the following message to your message processing section.


        .ElseIf Eax == WM_DESTROY       ; Destroy the window
          inv  SavToRegistry            ; Store any changes in the Registry, if you don't need this just remove it
          inv  DeleteObject, hFont      ; Delete the font
          inv  PostQuitMessage, NULL    ; Tell Windows that this thread has made a request to terminate (quit)


SetFormat cleans up its own created resource (hDC) so that hFont is the only resource I have introduced into your code that needs to be cleaned up.

Thank you, Manos for keeping me on the straight and narrow.
Paul

raymond

Quote from: donkey on December 28, 2004, 05:17:46 AM
Hi Raymond,

I grabbed this from NaN, it is what I use a reference when I need to print something...
Thanks donkey. I have used that also but I am still looking for WYSIWYG printing. farrier may provide what I need. Should be most interesting.

Raymond
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

pbrennick

Raymond,
Try mine:


;       Include Files
;       --------------------------------
        include \masm32\include\windows.inc
        include \masm32\include\user32.inc
        include \masm32\include\kernel32.inc
        include \masm32\include\comdlg32.inc
        include \masm32\include\gdi32.inc
;
;       Libraries
;       --------------------------------
        includelib  \masm32\lib\user32.lib
        includelib  \masm32\lib\kernel32.lib
        includelib  \masm32\lib\comdlg32.lib
        includelib  \masm32\lib\gdi32.lib


ErrorMsg        PROTO
PrintProc       PROTO

MOVmd   Macro Var1, Var2
        Push Var2
        Pop Var1
        EndM

MsgBox  Macro Resource:req, Title: = < ERROR > , Flags: = < MB_OK Or MB_ICONEXCLAMATION >
        Mov Eax, Resource
        Lea Ebx, Title
        Mov Ecx, Flags
        Call ErrorMsg
        EndM

inv     equ invoke
ERROR_NO_SELECTION  Equ 30012

.data
;---------------------------------------
FontName        DB  'Courier', 25 Dup (0)   ; 32 bytes max (including ASCIIZ terminator)

; Printer stuff
;---------------------------------------;
mB              DD  0                   ; Bottom margin of printed page
mL              DD  0                   ; Left margin of printed page
mR              DD  0                   ; Right margin of printed page
mT              DD  0                   ; Top margin of printed page
RTwips1000      Real10  1.44            ; Twips constant
w1              DD  0                   ; Scratch variable used when calculating margins
pTitle          DB  'GeneSys Editor', 0 ; Document Title
Sel             DD  0                   ; Flags a 'Range' type print job, currently unused
xPerInch        DD  0                   ; Width of printable area
yPerInch        DD  0                   ; Height of printable area
PrtHead         DD  1
PrtColor        DD  0
cnt             DD  0
szSelect        DB  'Selected Text!', 0
szWork          DB  256 Dup (?), 0
szNULL          DB  0                   ; Null value

.data?
;---------------------------------------
hREd            HWND    ?               ; Handle
hInstance       DD      ?               ; Handle
hWnd            HWND    ?               ; Handle

; Structures used by the Printer Routines
;---------------------------------------
doci    DOCINFO         <?>             ; Docinfo (printing support)
fr_1    FORMATRANGE     <?>             ; For EM_FORMATRANGE
pd      PRINTDLG        <?>             ; Print
rect_1  RECT            <?>             ; Rectangle
charF   CHARFORMAT2     <?>             ; For EM_GETCHARFORMAT/EM_SETCHARFORMAT
cr      CHARRANGE       <?>             ; Character range


PrintProc Proc
;---------------------------------------
        Local Chg:DWord, TextSize
        Local cf:CHOOSEFONT             ; Structure
;
        inv  SendMessage, hREd, EM_GETMODIFY, 0, 0
        Mov Chg, Eax
        Push cf.rgbColors
        Mov cf.rgbColors, 0
        inv  SendMessage, hREd, EM_SETBKGNDCOLOR, 0, 00FFFFFFH
        Pop cf.rgbColors
        Cmp PrtColor, 1
        Je StartPrt
        inv  SendMessage, hREd, EM_EXGETSEL, 0, Offset cr
        inv  SendMessage, hREd, EM_SETSEL, -1, 0
        Mov charF.dwMask, CFM_FACE Or CFM_SIZE Or CFM_COLOR
        Mov charF.crTextColor, 0
        inv  lstrcpy, Offset charF.szFaceName, Offset FontName
        inv  SendMessage, hREd, EM_SETCHARFORMAT, SCF_ALL, Offset charF
        inv  SendMessage, hREd, EM_EXSETSEL, 0, Offset cr
StartPrt:
        Mov cnt, 0
        Mov pd.lStructSize, SizeOf pd
        Mov Eax, hWnd
        Mov pd.hwndOwner, Eax
        Mov Eax, hInstance
        Mov pd.hInstance, Eax
        Mov pd.Flags, PD_RETURNDC
        inv  PrintDlg, Offset pd
        Cmp Eax, FALSE
        Je PrtRet
        Mov Eax, pd.Flags
        Mov Ebx, Eax
        And Ebx, 000000FFH
        Mov Sel, Ebx
        inv  SendMessage, hREd, EM_EXGETSEL, 0, Offset cr
        Mov Eax, cr.cpMax
        .If Eax > cr.cpMin && Sel != 1
          MsgBox ERROR_NO_SELECTION, szSelect, MB_YESNO Or MB_ICONQUESTION
          Cmp Eax, IDNO
          Je PrtRet
        .EndIf
        Mov doci.cbSize, SizeOf doci
        Mov doci.lpszDocName, Offset pTitle
        Mov doci.lpszOutput, 0
        Mov doci.fwType, 0
        Mov Eax, pd.hDC
        Mov fr_1.hdc, Eax
        Mov fr_1.hdcTarget, Eax  ;0
        inv  GetDeviceCaps, fr_1.hdc, LOGPIXELSX    ; Number of pixels per logical inch along the screen width.
        Mov xPerInch, Eax
        inv  GetDeviceCaps, fr_1.hdc, LOGPIXELSY    ; Number of pixels per logical inch along the screen height.
        Mov yPerInch, Eax
        Mov Eax, mL                    ; Min is 360
        Mov rect_1.left, Eax
        Mov Eax, mT                    ; Min is 360
        Mov rect_1.top, Eax
        .If PrtHead
          Add rect_1.top, 420          ; 360
        .EndIf
        inv  GetDeviceCaps, fr_1.hdc, HORZRES       ; Width, in pixels, of the screen.
        Mov Ecx, 1440
        Mul Ecx
        Div xPerInch
        Mov rect_1.right, Eax
        Mov Eax, mR                    ; Min is 360
        Sub rect_1.right, Eax
        inv  GetDeviceCaps, fr_1.hdc, VERTRES       ; Height, in raster lines, of the screen.
        Mov Ecx, 1440
        Mul Ecx
        Div yPerInch
        Mov rect_1.bottom, Eax
        Mov Eax, mB                    ; Min is 302
        Sub rect_1.bottom, Eax
        Mov Ecx, 16
        Mov Edi, Offset fr_1.rcPage
        Mov Esi, Offset rect_1
        Cld
        Rep Movsb
        inv  StartDoc, pd.hDC, Offset doci
        inv  SendMessage, hREd, EM_EXGETSEL, 0, Offset cr
        Mov Eax, cr.cpMin
        Mov Ebx, cr.cpMax
        .If Ebx > Eax && Sel == 1
          Mov fr_1.chrg.cpMin, Eax
          Mov fr_1.chrg.cpMax, Ebx
          Mov TextSize, Ebx
        .Else
          inv  SendMessage, hREd, EM_HIDESELECTION, 1, 0
          Mov cr.cpMin, 0
          Mov cr.cpMax, -1
          inv  SendMessage, hREd, EM_EXSETSEL, 0, Offset cr
          inv  SendMessage, hREd, EM_EXGETSEL, 0, Offset cr
          MOVmd fr_1.chrg.cpMin, cr.cpMin
          Mov fr_1.chrg.cpMax, -1
          MOVmd TextSize, cr.cpMax
          Mov cr.cpMin, 0
          Mov cr.cpMax, 0
          inv  SendMessage, hREd, EM_EXSETSEL, 0, Offset cr
          inv  SendMessage, hREd, EM_HIDESELECTION, 0, 0
        .EndIf
prtloop:
        inv  StartPage, pd.hDC
        Cmp Eax, 0
        Jle prtabort
        Mov Ecx, 16
        Mov Esi, Offset rect_1
        Mov Edi, Offset fr_1.rc        ; Actual print page dimensions
        Cld
        Rep Movsb
        inv  SendMessage, hREd, EM_FORMATRANGE, TRUE, Offset fr_1   ; Print page
        Mov fr_1.chrg.cpMin, Eax
        inv  EndPage, pd.hDC
        Cmp Eax, 0
        Jle prtabort
        Mov Eax, fr_1.chrg.cpMin
        Cmp Eax, 0
        Jle prtdone
        Cmp Eax, TextSize
        Jl prtloop
prtdone:
        inv  SendMessage, hREd, EM_FORMATRANGE, 0, 0
        inv  EndDoc, pd.hDC
        inv  DeleteDC, pd.hDC
        Jmp PrtRet
prtabort:
        inv  AbortDoc, fr_1.hdc
PrtRet: Ret
;---------------------------------------
PrintProc EndP

; _____________________________
;|                             |
;| Generate error message      |
;|  eax = message # to display |
;|  ebx = Title                |
;|  ecx = MessageBox Flags     |
;|_____________________________|
;
ErrorMsg Proc
;---------------------------------------;
        Push Ecx                        ;
        Push Ebx                        ; Save these for after LoadString call
        Push LengthOf szWork            ; Size of our buffer
        Push Offset szWork              ; Buffer to load string into
        Push Eax                        ; Resource #
        Push hInstance                  ; Instance
        Call LoadString                 ; Load the tip from STRINGTABLE
        Cmp Eax, 0                     ; Did we get a string?
        Jne Error1                     ; Yes, continue
        Lea Eax, szNULL                ; Null string
Error1: Push Offset szWork
        Push 0
        Call MessageBox
        Ret
;-------------------------------------
ErrorMsg EndP


I have included all the variable and structures needed.

        call    PrintProc

The above line is used to call the procedure

Paul

Robert Collins

Hi Paul.

Thanks for your sample.

Well, using your sample code I finally got most of it to work but there are a couple of things that I am still in the dark about.

First, I found out about the lfnt.?????? stuff and already created a LOGFONT structure.

Second, After I took a guess about 'hREd' I changed it to 'hRichEdit' and that solved that problem.

Third, as far as the 'rgb' variable I used the one in the Tutorial 'TextColor'

OK, now the problems:

You say that 'TabSize' will be set to 4. I cannot find anyplace in the code where this variable is
initialized to any value.

Here are some things that I do not understand in your proc 'SetFormat'

At the Create font section you initialize the LOGFORMAT structure for the lfnt.lfHeight and the
lfnt.lfWeight but you do not do anything with the other elements of the structure. I am assuming that
it doesnt matter.

Now, down at the section where you set the charset I see that you have the following lines of code:


  '
  '
  '
  mov   al, lfnt.lfCharSet         ; Get current character set
  mov   cf.bCharSet, al         ; Store it in the structure

  mov   al, lfnt.lfPitchAndFamily  ; Get character styles
  mov   cf.bPitchAndFamily, al     ; Store it in the structure
  .
  .


However, I cannot find anywhere where you have previously initialized lnft.lfCharSet nor lfnt.lfPitchAndFamily
but you are moving their contents into the CHARFORMAT structure.

And now the final and most important problem. I have been able to get the font and point size I like but no
matter what I do I am unable to remove the BOLD look to any font that I decided to use. FIXEDSYS comes
out looking very thick and black, so much that it is ugly. Why wasn't the font weight (400 for normal) effective
when the font was created? Where in the other structures does one control whether the font is bold or not.
I can change the font to Italics, Underscore, Strikeout but I cannot get rid of that bold look.