--- title: "Deskjet Print Filter" type: "article" slug: "deskjet-print-filter" url: "http://localhost/article/deskjet-print-filter/" markdown_url: "http://localhost/article/deskjet-print-filter.md" published_at: "2025-12-18T18:35:52+00:00" modified_at: "2026-06-21T23:21:28+00:00" featured_image: url: "http://localhost/wp-content/uploads/2022/04/20230809-041332.jpg" excerpt: "Once I got my DeskJet printer, I wanted to be able to produce nice looking text output. Quill and other word processors support only monospace fonts. The word processors that do support proportional spaced fonts are not real cheap. Being one to write my own print filters, I set myself out to write a print…" category: - name: "QL Hacker's Journal" slug: "ql-hackers-journal" taxonomy: "category" url: "http://localhost/category/periodicals/ql-hackers-journal/" post_tag: - name: "Full Text" slug: "fulltext" taxonomy: "post_tag" url: "http://localhost/tag/fulltext/" - name: "QL" slug: "ql" taxonomy: "post_tag" url: "http://localhost/tag/ql/" - name: "Superbasic (programming language)" slug: "superbasic-programming-language" taxonomy: "post_tag" url: "http://localhost/tag/superbasic-programming-language/" model: - name: "Sinclair QL" slug: "sinclair-ql" taxonomy: "model" url: "http://localhost/model/sinclair-ql/" indiv: - name: "Tim Swenson" slug: "tim-swenson" taxonomy: "indiv" url: "http://localhost/indiv/tim-swenson/" publication_r: id: 33686 title: "QL Hacker’s Journal" type: "periodical" url: "http://localhost/periodical/ql-hackers-journal/" authors_r: - name: "Tim Swenson" slug: "tim-swenson" taxonomy: "indiv" url: "http://localhost/indiv/tim-swenson/" issue: "23" issues_articles: - id: 61559 title: "QL Hacker’s Journal 23" type: "issue" url: "http://localhost/issue/ql-hackers-journal-23/" pubdate: "January 1996" archive_link: true --- # Deskjet Print Filter Once I got my DeskJet printer, I wanted to be able to produce nice looking text output. Quill and other word processors support only monospace fonts. The word processors that do support proportional spaced fonts are not real cheap. Being one to write my own print filters, I set myself out to write a print filter that will support word wrap and proportional spaced fonts. dj_print is such a printer filter. I could not find any documentation giving me the physical size of the various characters, so I had to do some testing and a bit of guessing. These numbers are used in an array to add up how big a line is before word wrapping it. I have only done these calculations for 12 pitch, so the program will not work well for other pitches. Centering of text still needs to be worked on, esp. with different pitch sizes. So this all turns out that the program only supports regular text at 12 pitch and centered text at 14 pitch (for nice headers). As for the commands that dj_print supports, they are listed in the procedure command. Like my other print filters, dj_print uses dot commands, like .BD. They should be on a line by themselves. Remember, this code is a project in the works. In other words, it still needs some work, but will pretty much do the job. ``` ** DJ Print ssb 2.0 ** This version supports proportional fonts OPEN #5,con_250x150A75x75_32 PAPER #5,4 : INK #5,0 : BORDER #5,7 CLS #5 PRINT #5,"Enter Name of File to Print :" INPUT #5," ";infile$ ** Default print size is 12 Point ** Default type is CG Times ** CG Times ESC (s1p12v0s0b4101T ** Univers ESC (s1p12v0s0b52T ** Times Roman ESC (s1p12v0s0b5T ** Helvetica ESC (s1p12v0s0b4T DIM word_array$(30,40) DIM letter_width(126) RESTORE FOR x = 32 TO 126 READ temp letter_width(x) = temp NEXT x ** Letter Size Data for 12 Point letters DATA 3.8,5,5.5,12.5,8.3,14.2,14.2,3.8,6.2,6.2,9,14.2 DATA 3.8,5.5,3.8,8.3,8.3,8.3,8.3,8.3,8.3,8.3,8.3,8.3 DATA 8.3,8.3,4.5,4.5,14.2,14.2,14.2,8.3,16.6,12.5,11.1,11.1 DATA 12.5,11.1,10,14.2,14.2,5.5,7.1,12.5,11.1,16.6,12.5,12.5 DATA 10,12.5,12.5,9,11.1,14.2,12.5,14.2,12.5,12.5,12.5,5,8.3 DATA 5,8.3,8.3,3.8,8.3,9,7.1,9,8.3,5.8,7.6,9,4.5,4.5,8.3,4.5 DATA 14.2,9,9,9,9,6.2,6.2,5,9,8.3,14.2,8.3,8.3,7.1,8.3,6.6 DATA 8.3,14.2 OPEN_IN #4,infile$ OPEN #3,ser1 ** Set Program Defaults YES = 1 NO = 0 type$="4101T" cde = NO center = NO margin = 500 line_length = 0 PRINT #3,CHR$(27);"(s1p12v0s0b";type$ PRINT #3,CHR$(27);"&a10L"; REPeat loop ** Get the next line of text INPUT #4,in$ IF EOF(#4) THEN EXIT loop ** If the line is blank then output a CR/LF to end ** the last paragraph and another LF to create ** a space between the two paragraphs. IF LEN(in$) = 0 THEN PRINT #3,CHR$(13) PRINT #3,"" line_length = 0 END REPeat loop END IF IF LEN(in$) >=3 AND in$(1) = "." THEN command END REPeat loop END IF ** If the line is to be Centered IF center = YES THEN word_size = 0 ** Find out how wide line is FOR z = 1 TO LEN(in$) word_size=word_size+letter_width(CODE(in$(z))) NEXT z ** Determine how much to space over line temp = INT(((margin - word_size)/2)/3.8) ** Print the write number of spaces FOR z = 1 to temp PRINT #3," "; NEXT z PRINT #3,in$;CHR$(13) END REPeat loop END IF ** If the line is Program Code IF cde = YES THEN ** do no processing on text PRINT #3,in$;CHR$(13) END REPeat loop END IF char = 1 word_count = 1 ** Split out all the words in a line into an array. ** Leading spaces and extra spaces between words are ** ignored. REPEAT word IF char > LEN(in$) THEN EXIT word char$ = in$(char) ** Take out leading spaces IF char$ = " " AND char=1 THEN ## If in$ ends in a space IF char+1 > LEN(in$) THEN EXIT word in$ = in$(char+1 TO ) char = 1 END REPEAT word END IF ** Find end of word by finding the next space IF char$ = " " THEN word_array$(word_count) = in$(1 TO char-1) IF char+1 > LEN(in$) THEN in$ = " " ELSE in$ = in$( char+1 TO ) END IF word_count = word_count + 1 char = 1 END IF ** Find end of word by the end of the string IF char = LEN(in$) THEN word_array$(word_count) = in$ word_count = word_count + 1 EXIT word END IF char = char + 1 END REPEAT word ** Now go through each word FOR x = 1 TO word_count - 1 word_size = 0 word$ = word_array$(x) FOR z = 1 TO LEN(word$) word_size = word_size + letter_width(CODE (word$(z))) NEXT z IF line_length + word_size > margin THEN PRINT #3,chr$(13) line_length = 0 END IF PRINT #3,word$;" "; line_length = line_length + word_size + 3.8 NEXT x END REPeat loop PRINT #3,CHR$(27);"&l0H" CLOSE #3 CLOSE #4 CLOSE #5 DEFine PROCedure command cmd$ = in$(1 TO 3) ** Page Break IF cmd$=".pd" OR cmd$=".PB" THEN PRINT #3,CHR$(12); ** Bold IF cmd$=".bd" OR cmd$=".BD" THEN PRINT #3,CHR$(27); "(s3B"; IF cmd$=".bo" OR cmd$=".BO" THEN PRINT #3,CHR$(27); "(s0B"; ** Underline (fixed and floating) IF cmd$=".ul" OR cmd$=".UL" THEN PRINT #3,CHR$(27); "&d1D"; IF cmd$=".uf" OR cmd$=".UF" THEN PRINT #3,CHR$(27); "&d3D"; IF cmd$=".uo" OR cmd$=".UO" THEN PRINT #3,CHR$(27); "&d";CHR$(64); ** Italics IF cmd$=".it" OR cmd$=".IT" THEN PRINT #3,CHR$(27); "(s1S"; IF cmd$=".io" OR cmd$=".IO" THEN PRINT #3,CHR$(27); "(s0S"; ** Large Letters (14 Point) IF cmd$=".lg" OR cmd$=".LG" THEN PRINT #3,CHR$(27); "(s1p14v0s0b";type$; IF cmd$=".lo" OR cmd$=".LO" THEN PRINT #3,CHR$(27); "(s1p12v0s0b";type$; ** CG Times IF cmd$=".cg" OR cmd$=".CG" THEN type$="4101T" PRINT #3,CHR$(27);"(s1p12v0s0b";type$; END IF ** Univers IF cmd$=".uv" OR cmd$=".UV" THEN type$="52T" PRINT #3,CHR$(27);"(s1p12v0s0b";type$; END IF ** Times Roman IF cmd$=".tr" OR cmd$=".TR" THEN type$="5T" PRINT #3,CHR$(27);"(s1p12v0s0b";type$; END IF ** Helvetica IF cmd$=".hv" OR cmd$=".HV" THEN type$="4T" PRINT #3,CHR$(27);"(s1p12v0s0b";type$; END IF ** New Paragraph IF cmd$=".pp" OR cmd$=".pp" THEN PRINT #3,CHR$(13) line_length = 0 END IF IF cmd$=".tb" OR cmd$=".TB" THEN ** We hope there is a number after .tb tab = in$(5 TO ) IF tab = 1 THEN PRINT #3,CHR$(9); ELSE FOR z = 1 TO tab PRINT #3,CHR$(9); NEXT z END IF END IF ** Center Text IF cmd$=".ct" OR cmd$=".CT" THEN center=YES IF cmd$=".co" OR cmd$=".CO" THEN center=NO ** Program Code IF cmd$=".pc" OR cmd$=".PC" THEN PRINT #3,CHR$(27);"(s0p10h0s0b3T"; cde=YES END IF IF cmd$=".po" OR cmd$=".PO" THEN PRINT #3,CHR$(27);"(s1p12v0s0b";type$; cde=NO END IF END DEFine command ```