2019-04-05

GF TextUtil debug 雜記

自從在前前公司接觸 GXT、接著把 Chart 的底層 DrawComponent 給翻了一遍之後,就對這玩意很感興趣,之後陸陸續續以 DrawComponent 為基礎搞了一些東西出來。去年終於搞了一個 GF 版的 TextButton 出來。TextButton重點 惡搞之處在於文字的字體會隨著整體大小而自動調整。好不好用很難說,自己是頗為得意啦… 囧>,因為算是集大成之作:

  • 驗證了 GF Layer 機制的可用性
  • 處理 TextSprite 在視覺上的 y 軸位移問題(雖然沒有相對正統地用後來搞出來的 FontMatrics 來校正 XD)
  • 大幅解決效率問題(因為發現有 Sprite.redraw() 而不用每次都搞 DrawComponent.redraw()

不過實務上陸陸續續有炸出一些問題,在某些狀況下初始的字體並沒有變成正確的大小。但是因為一直都能 workaround 掉,所以沒提煉 SSCCE、自然也沒深究

這幾天又被炸到,在試圖解決的過程當中得到了一個很奇妙的結果,細節寫在 GF 的 Issue 裡頭,這裡就不贅述了。 此時都懷疑問題出在 GXT、或是 browser 原生特性,沒有想過是 GF 的問題。 現在檢討起來是非常搞笑啦,不過那時覺得很合理,因為經驗當中對付 DrawComponent 就遇到一些奇妙無法解釋的事情,例如 TextSprite 一定要 redraw() 之後才能得到正確的 bbox、但是 TextSprite.setText() 不用 redraw() 就能反應在畫面上… 另外,當下測試出來的結果很奇葩可能也是原因之一,至少到現在還是無法解釋為什麼一定要 onSize() 兩次加上 deferred command 就能正常顯示。

因為正職是家庭煮夫,所以光是這段就花了快一個禮拜的時間。接著又花了一兩天在想該不該把這東西寫成 LayerContainer 的行為以絕後患,要的話又該怎麼寫才好。

然後越想越不對勁… XD

起點是「就為了 TextButton / TextSprite 把這個擺明效率不好的行為變成預設值,這樣真的好嗎?」… 等等,為什麼只有 TextSprite?底下作為背景的 RectangleSprite 大小一直都是正確的阿?

於是又回頭重測,這次拔光光只針對 TextSpritebbox,確認同樣 scenario 下只要有作 Sprite.redraw()bbox 的值就會正常,完全不需要搞什麼作兩次還是 deferred command… 這下尷尬了,根本不是什麼 browser 特性還是 GXT 問題,是 GF 有 bug。

重新檢視了一下 TextUtil.autoResize(),在第一次取 bbox 之前並沒有保證作過 Sprite.redraw()。之前會正確顯示多半是其他環節跟機制讓 TextButton 裡頭的 TextSprite 有機會作 redraw()。所以只要在那之前作一次 text.redraw() 就沒事了。

更有趣的事情還在後頭。

當初寫 TextUtil 的時候,因為陸續炸了很多哏,所以註解算是寫的很勤勞了;而那時早就已經知道要 redraw() 才能得到正確的 bbox,還有寫在註解裡頭。但是「為什麼第一次取 bbox 之前沒作 redraw()」卻完全沒寫,現在自然也想不起來當時到底是忘記要寫、還是因為某個神秘原因所以不做。

另外,這還是不能解釋為什麼原本的 autoResize() 無法正常處理字體需要放大的 case、也不能解釋為什麼 issue #37 找出來的排列組合能正常或是不正常… 不過我不想繼續再追下去了… (艸

如果這一串下來,我(再次)得到的教訓是:

  • SSCCE 很實在,TDD 核心思想有其道理
  • 註解永遠不嫌少,記憶永遠不可靠
  • 不管機率高低,該懷疑的還是要重新檢視一遍
  • 對底層的瞭解度越高,就越不會把 workaround 當成正解
  • 時間越充裕,就越不會把 workaround 當成正解。
    • 如果是在職場,有 94.87% 的機率會直接把 issue #37 的結論當作正解。