英語版の花文字テキストを作成してテキストエディタ(CotEditor)に出力するAppleScriptです。
描画用の英単語と、塗りつぶし用の英単語を別々に指定できます。invertFをtrueに設定すると、白黒反転出力を行います。
おおもとの元ネタは、大型計算機を大勢のユーザーで共有していた時代(ぱそこん登場前)、計算結果を高速プリンタの帳票に出力するようになっていたころにさかのぼります。どのユーザーの計算結果かを大量のプリンタの出力結果の中から仕分けるため、印刷出力の1ページ目をユーザー名などの情報を印字した「バナー」として使用。
そのさい、ドットインパクトプリンターだったので、決められた固定ドット数の文字しか印字できないため、英数字を組み合わせて擬似的に大きな文字でバナーを印刷していたことに端を発します。
その時代の「残り香」ともいえるバナーがパソコンの電子メールやBBSの時代にお遊びの「花文字」として引き継がれ、原始的なアスキーアートの一種として楽しまれてきました。
いまでも、shell commandの「banner」コマンドにその末裔を見ることができます。
先週のmacOS nativeのデモ時に「祝」という花文字を「呪」の文字で出力するという、定番の持ちネタを披露したところ、たいへんウケておりました。
ただ、これを海外のScripter向けにそのままデモしても受けません。
この、花文字テキストを出力するプログラムの英語版としては、love.scptといういにしえのデータをそのまま使いまわしたものがありますが、描画パターンを数値データで保持しているため、異なるパターンを表示させることはできません。
そこで、日本語版の花文字テキスト出力プログラムに若干手をくわえ、英単語の出力が行えるようにしてみました。
テキストの出力はCotEditorに対して行なっていますが、新規書類を指定文字で作成する程度なので、AppleScriptに対応しているテキストエディタならどれでも作り変えられます。また、表示を等幅フォントにしておく必要があります(あとから指定してもOK)。
AppleScript名:指定単語の花文字テキストを取得する(Retina対応)英文字用 v2 |
— Created 2017-12-12 by Takaaki Naganoya — Modified 2019-03-29 by Takaaki Naganoya — 2019 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "AppKit" property NSFont : a reference to current application’s NSFont property NSUUID : a reference to current application’s NSUUID property NSColor : a reference to current application’s NSColor property NSArray : a reference to current application’s NSArray property NSString : a reference to current application’s NSString property NSImage : a reference to current application’s NSImage property NSPredicate : a reference to current application’s NSPredicate property NSDictionary : a reference to current application’s NSDictionary property NSBezierPath : a reference to current application’s NSBezierPath property NSColorSpace : a reference to current application’s NSColorSpace property NSPNGFileType : a reference to current application’s NSPNGFileType property NSFontManager : a reference to current application’s NSFontManager property NSBitmapImageRep : a reference to current application’s NSBitmapImageRep property NSMutableDictionary : a reference to current application’s NSMutableDictionary property NSFontAttributeName : a reference to current application’s NSFontAttributeName property NSKernAttributeName : a reference to current application’s NSKernAttributeName property NSMutableParagraphStyle : a reference to current application’s NSMutableParagraphStyle property NSLigatureAttributeName : a reference to current application’s NSLigatureAttributeName property NSMutableAttributedString : a reference to current application’s NSMutableAttributedString property NSUnderlineStyleAttributeName : a reference to current application’s NSUnderlineStyleAttributeName property NSParagraphStyleAttributeName : a reference to current application’s NSParagraphStyleAttributeName property NSForegroundColorAttributeName : a reference to current application’s NSForegroundColorAttributeName property fillCharList : {} property fillCharCounter : 1 set aString to "Love" set bString to "hate" set hanaSize to 24 set thisFont to selectAFont(first character of aString) of me if thisFont = false then return –Cancel –花文字文字列を作成 set fRes to getEnglishHanamojiStr(hanaSize, thisFont, aString, bString, 0.7, true, true) of me makeNewDocument given parameter:fRes –花文字文字列を計算して返す on getEnglishHanamojiStr(aFontSize as real, aFontName as string, aString as string, fillString as string, aThread as real, incFontName as boolean, invertF as boolean) set my fillCharList to characters of fillString set my fillCharCounter to 1 –指定文字コードが指定フォント中に存在するかチェック repeat with i in (characters of aString) set fRes to retGlyphsInFont(aFontName, id of i) of me if fRes = false then return false end repeat set aThreadShould to 768 * aThread if (chkMultiByteChar(first character of aString) of me) = false then set spaceChar to string id 12288 –全角スペース(UTF-16) else set spaceChar to string id 32 –半角スペース end if set fillColor to NSColor’s whiteColor –塗り色 set bString to aString & " " –処理内容の帳尻合わせ(そのままだと右端が欠けるのでスペースを入れた) set anAssrStr to makeRTFfromParameters(bString, aFontName, aFontSize, -2, (aFontSize * 1.2)) of me set aSize to anAssrStr’s |size|() if class of aSize = record then set attrStrWidth to width of aSize set attrStrHeight to height of aSize else if class of aSize = list then –macOS 10.13.xのバグ回避 copy aSize to {attrStrWidth, attrStrHeight} end if set {xPos, yPos} to {0, 0} set tmpImg1 to makeImageWithFilledColor(attrStrWidth, attrStrHeight, fillColor) of me set tmpImg2 to drawAttributedStringsOnImage(tmpImg1, anAssrStr, xPos, yPos) of me set aRawimg to NSBitmapImageRep’s imageRepWithData:(tmpImg2’s TIFFRepresentation()) –画像から順次指定座標の色データを拾って花文字listに反映 set strList to {} repeat with y from 1 to attrStrHeight – 1 set strListX to {} repeat with x from 0 to attrStrWidth – 1 set tmpCol to getColorFromRawImage(aRawimg, x, y) of me if invertF = false then –通常描画(invert = false)時 if tmpCol is not equal to false then if tmpCol is not equal to {255, 255, 255} then copy tmpCol to {tmpR, tmpG, tmpB} if (tmpR + tmpG + tmpB) < aThreadShould then set the end of strListX to getChar() of me else set the end of strListX to spaceChar end if else set the end of strListX to spaceChar end if end if else –白黒反転(invert = true)時 if tmpCol is not equal to false then if tmpCol is not equal to {255, 255, 255} then copy tmpCol to {tmpR, tmpG, tmpB} if (tmpR + tmpG + tmpB) < aThreadShould then set the end of strListX to spaceChar else set the end of strListX to getChar() of me end if else set the end of strListX to getChar() of me end if end if end if end repeat set the end of strList to strListX end repeat –2D List→Text set aRes to list2dToStringByUsingDelimiters(strList, "", return) of me if incFontName = true then set fName to getDisplayedNameOfFont(aFontName) of me set aRes to "Font=" & fName & return & return & aRes end if return aRes end getEnglishHanamojiStr on getChar() set retChar to item (my fillCharCounter) of (my fillCharList) if (my fillCharCounter) = length of (my fillCharList) then set (my fillCharCounter) to 1 else set (my fillCharCounter) to (my fillCharCounter) + 1 end if return retChar end getChar –指定Raw画像中の指定座標のピクセルの色をRGBで取り出す on getColorFromRawImage(aRawimg, x as real, y as real) set aRatio to getImageRatio() of me –Retina Display対応 set origColor to (aRawimg’s colorAtX:(x * aRatio) y:(y * aRatio)) set srgbColSpace to NSColorSpace’s deviceRGBColorSpace if srgbColSpace = missing value then return false set aColor to (origColor’s colorUsingColorSpace:srgbColSpace) set aRed to (aColor’s redComponent()) * 255 set aGreen to (aColor’s greenComponent()) * 255 set aBlue to (aColor’s blueComponent()) * 255 return {aRed as integer, aGreen as integer, aBlue as integer} end getColorFromRawImage –画像のうえに指定のスタイル付きテキストを描画して画像を返す on drawAttributedStringsOnImage(anImage, anAssrStr, xPos as real, yPos as real) anImage’s lockFocus() anAssrStr’s drawAtPoint:(current application’s NSMakePoint(xPos, yPos)) anImage’s unlockFocus() return anImage end drawAttributedStringsOnImage –書式つきテキストを組み立てる on makeRTFfromParameters(aStr as string, fontName as string, aFontSize as real, aKerning as real, aLineSpacing as real) set aVal1 to NSFont’s fontWithName:fontName |size|:aFontSize set aKey1 to (NSFontAttributeName) set aVal2 to NSColor’s blackColor() set aKey2 to (NSForegroundColorAttributeName) set aVal3 to aKerning set akey3 to (NSKernAttributeName) set aVal4 to 0 set akey4 to (NSUnderlineStyleAttributeName) set aVal5 to 2 –all ligature ON set akey5 to (NSLigatureAttributeName) set aParagraphStyle to NSMutableParagraphStyle’s alloc()’s init() aParagraphStyle’s setMinimumLineHeight:(aLineSpacing) aParagraphStyle’s setMaximumLineHeight:(aLineSpacing) set akey7 to (NSParagraphStyleAttributeName) set keyList to {aKey1, aKey2, akey3, akey4, akey5, akey7} set valList to {aVal1, aVal2, aVal3, aVal4, aVal5, aParagraphStyle} set attrsDictionary to NSMutableDictionary’s dictionaryWithObjects:valList forKeys:keyList set attrStr to NSMutableAttributedString’s alloc()’s initWithString:aStr attributes:attrsDictionary return attrStr end makeRTFfromParameters –指定サイズの画像を作成し、背景を指定色で塗る on makeImageWithFilledColor(aWidth as real, aHeight as real, fillColor) set anImage to NSImage’s alloc()’s initWithSize:(current application’s NSMakeSize(aWidth, aHeight)) set aRatio to getImageRatio() of me –Retina Display対応 anImage’s lockFocus() set theRect to {{x:0, y:0}, {width:aWidth * aRatio, height:aHeight * aRatio}} set theNSBezierPath to NSBezierPath’s bezierPath theNSBezierPath’s appendBezierPathWithRect:theRect fillColor’s |set|() theNSBezierPath’s fill() anImage’s unlockFocus() return anImage end makeImageWithFilledColor –2D Listをアイテム間および行間のデリミタを個別に指定してテキスト変換 on list2dToStringByUsingDelimiters(aList as list, itemDelimiter, lineDelimiter) set outList to {} repeat with i in aList set aStr to listToStringUsingTextItemDelimiter(i, itemDelimiter) of me set the end of outList to aStr end repeat set bStr to listToStringUsingTextItemDelimiter(outList, lineDelimiter) of me return bStr end list2dToStringByUsingDelimiters on listToStringUsingTextItemDelimiter(sourceList as list, textItemDelimiter) set CocoaArray to NSArray’s arrayWithArray:sourceList set CocoaString to CocoaArray’s componentsJoinedByString:textItemDelimiter return (CocoaString as string) end listToStringUsingTextItemDelimiter –ユーザー環境にインストールされているすべてのフォントのPostScript名とグリフ数を返す on getEveryFontPSNameANdGlyphsNum(aStr) set aFontList to NSFontManager’s sharedFontManager()’s availableFonts() set thePred to NSPredicate’s predicateWithFormat:"NOT SELF BEGINSWITH ’.’" set aFontList to (aFontList’s filteredArrayUsingPredicate:thePred) as list set aList to {} repeat with i in aFontList set aName to contents of i set aNum to countNumberOfGlyphsInFont(aName) of me set dName to getDisplayedNameOfFont(aName) of me set fRes to retGlyphsInFont(aName, id of aStr) of me if fRes = true then set the end of aList to {fontName:aName, fontNum:aNum, dispName:dName} end if end repeat return aList end getEveryFontPSNameANdGlyphsNum –指定Postscript名称のフォントに定義されている文字数を数えて返す on countNumberOfGlyphsInFont(fontName as string) set aFont to NSFont’s fontWithName:fontName |size|:9.0 if aFont = missing value then return false set aProp to aFont’s numberOfGlyphs() return aProp as number end countNumberOfGlyphsInFont –フォントのPostScript NameからDisplayed Nameを取得 on getDisplayedNameOfFont(aName as string) set aFont to NSFont’s fontWithName:aName |size|:9.0 set aDispName to (aFont’s displayName()) as string return aDispName end getDisplayedNameOfFont –全角文字が存在するか on chkMultiByteChar(checkString as string) set aStr to NSString’s stringWithString:checkString set aRes to aStr’s canBeConvertedToEncoding:(current application’s NSASCIIStringEncoding) return (aRes as boolean) end chkMultiByteChar –指定名称のフォントに指定の文字コードが含まれているかチェック on retGlyphsInFont(fontName as string, strCode as integer) set aFont to NSFont’s fontWithName:fontName |size|:24.0 if aFont = missing value then return false set aSet to aFont’s coveredCharacterSet() set aRes to (aSet’s characterIsMember:strCode) as boolean return aRes as list of string or string –as anything end retGlyphsInFont on selectAFont(aString) set fRes to getEveryFontPSNameANdGlyphsNum(aString) of me set theArray to NSArray’s arrayWithArray:fRes set thePred to NSPredicate’s predicateWithFormat:"fontNum > 10000" set bArray to ((theArray’s filteredArrayUsingPredicate:thePred)’s valueForKeyPath:"dispName") as list set thisFont to choose from list bArray return thisFont end selectAFont –Retina Display対応ルーチン on getImageRatio() set retinaF to detectRetinaDisplay() of me if retinaF = true then return 2.0 as real else return 1.0 as real end if end getImageRatio on detectRetinaDisplay() set dispList to current application’s NSScreen’s screens() set retinaF to false repeat with i in dispList set j to contents of i set aDepth to j’s backingScaleFactor() if aDepth > 1.0 then set retinaF to true end if end repeat return retinaF end detectRetinaDisplay on makeNewDocument given parameter:aStr tell application id "com.coteditor.CotEditor" activate set newDoc to make new document tell newDoc set contents to aStr end tell end tell end makeNewDocument |
love – AppleScriptの穴 says:
[…] → その後、英単語の花文字プログラムを作成してみました。 […]