上次用了”麻木”這個形容詞,這次要用”渾渾噩噩”。
- 武俠梁祝 • Butterflylovers(Wikipedia)。其實這部片裡,最令我驚訝的是有庾澄慶,我真的想不到他會來演電影。這部片子普普通通啦,所以台灣票房好像也不是很好…
- Bedtime Stories
(IMDB, Wikipedia),中譯:天方夜談。故事普普通通,沒有電影預告說的那樣好看。女主角:Keri Russell蠻正的,在片中沒什麼發揮,可惜了。
Just thinking more…
上次用了”麻木”這個形容詞,這次要用”渾渾噩噩”。
(IMDB, Wikipedia),中譯:天方夜談。故事普普通通,沒有電影預告說的那樣好看。女主角:Keri Russell蠻正的,在片中沒什麼發揮,可惜了。
不知道是我冷感還是怎樣,看這兩部片的時候,有種麻木的感覺~就跟西伯利亞歇斯底里症候群一樣~
如果你不知道這種病,不妨看看村上的國境之南太陽之西。
GObject、Gio、Gtk、Glib、Clutter 等在範例裡看到的 library,在 Seed 原始碼裡是看不到的,Seed 是利用 GObject Introspection 來跟這些 library 互動。
Cairo、sqlite、readline 的話,因為並沒有使用 GObject 這個 library,所以 Seed 另外寫 Module 來跟這些 library 互動,你可以在 Seed 原始碼的 modules 目錄下看到~
Cairo 實際上是在 Canvas 這個 module 裡,Canvas 裡共有四個主要的類別:CairoCanvas、PDFCanvas、SVGCanvas、ImageCanvas,創建這些 Canvas 以後,基本上都是使用 Cairo 來在這些 Canvas 上繪圖。裡面沒有封裝 cairo_pattern_xxxx、cairo_text_xxxx、cairo_mask…等函數,所以不能用 Cairo 來繪圖或是繪字。
#!/usr/bin/env seed Seed.import_namespace("Gtk"); Seed.import_namespace("Canvas"); Seed.import_namespace("Gdk"); // // Initialize GTK+ // Gtk.init(null, null); // Create the main application window and set the title var window = new Gtk.Window({title: "Canvas Demo"}); var vbox = new Gtk.VBox(); var drawingArea = new Gtk.DrawingArea(); var status = new Gtk.Statusbar(); var hbox = new Gtk.HBox(); var exposeEvent = function() { return true;}; // // create Cairo Canvas // function createCairoCanvas() { var cairo = Gdk.cairo_create( drawingArea.window ); return new Canvas.CairoCanvas( cairo ); } // // Demos from http://cairographics.org/tutorial/ // function strokeDemo() { drawingArea.window.clear(); var canvas = createCairoCanvas(); canvas.strokeStyle = "rgb( 0, 0, 255 )"; canvas.strokeRect( 10, 10, 50, 50 ); canvas.stroke(); return true; } function fillDemo() { drawingArea.window.clear(); var canvas = createCairoCanvas(); canvas.fillStyle = "rgb( 0, 0, 255 )"; canvas.fillRect( 10, 10, 50, 50 ); canvas.fill(); return true; } function fourColorDemo() { drawingArea.window.clear(); var canvas = createCairoCanvas(); canvas.strokeStyle = "rgb( 0, 0, 0 )"; canvas.moveTo( 0, 0 ); canvas.lineTo( 100, 100 ); canvas.moveTo( 100, 0 ); canvas.lineTo( 0, 100 ); canvas.lineWidth = 10; canvas.stroke(); canvas.fillStyle = "rgb( 255, 0, 0 )"; canvas.globalAlpha = 0.8; canvas.fillRect( 0, 0, 50, 50 ); canvas.fillStyle = "rgb( 0, 255, 0 )"; canvas.globalAlpha = 0.6; canvas.fillRect( 0, 50, 50, 50 ); canvas.fillStyle = "rgb( 0, 0, 255 )"; canvas.globalAlpha = 0.4; canvas.fillRect( 50, 0, 50, 50 ); return true; } function pathDemo() { drawingArea.window.clear(); var canvas = createCairoCanvas(); canvas.strokeStyle = "rgb( 255, 0, 0 )"; canvas.beginPath(); canvas.moveTo( 25, 25 ); canvas.lineTo( 50, 37.5 ); canvas.lineTo( 75, 25 ); canvas.arc( 50, 50, 25*Math.sqrt(2), -0.25*Math.PI, 0.25*Math.PI, false ); canvas.bezierCurveTo( 50, 37.5, 50, 62.5, 25, 75 ); canvas.closePath(); canvas.stroke(); return true; } function scaleAndTransformDemo() { drawingArea.window.clear(); var canvas = createCairoCanvas(); canvas.strokeStyle = "rgb( 255, 0, 0 )"; canvas.lineWidth=10; canvas.save(); canvas.scale( 0.5, 1 ); canvas.arc( 50, 50, 40, 0, 2*Math.PI, true ); canvas.stroke(); canvas.translate( 100, 0 ); canvas.arc( 50, 50, 40, 0, 2*Math.PI, true ); canvas.restore(); canvas.stroke(); return true; } // // Demos from http://cairographics.org/samples/ // function arcDemo() { drawingArea.window.clear(); var canvas = createCairoCanvas(); var xc = 128; var yc = 128; var radius = 100; var angle1 = 45 * (Math.PI/180); var angle2 = 180 * (Math.PI/180); canvas.lineWidth = 10; canvas.arc( xc, yc, radius, angle1, angle2, true ); canvas.stroke(); canvas.fillStyle = "rgb( 255, 51, 51 )"; canvas.globalAlpha = 0.6; canvas.lineWidth = 6; canvas.arc( xc, yc, 10, 0, 2*Math.PI, true ); canvas.fill(); canvas.arc( xc, yc, radius, angle1, angle2, true ); canvas.lineTo( xc, yc ); canvas.arc( xc, yc, radius, angle2, angle2, true ); canvas.lineTo( xc, yc ); canvas.stroke(); return true; } function clipDemo() { drawingArea.window.clear(); var canvas = createCairoCanvas(); canvas.arc( 128, 128, 76.8, 0, 2*Math.PI, true ); canvas.clip(); canvas.beginPath(); canvas.fillRect( 0, 0, 256, 256 ); canvas.strokeStyle = "rgb( 0, 255, 0)"; canvas.moveTo( 0, 0 ); canvas.lineTo( 256, 256 ); canvas.moveTo( 256, 0 ); canvas.lineTo( 0, 256 ); canvas.lineWidth = 10; canvas.closePath(); canvas.stroke(); return true; } function curveRectangleDemo() { drawingArea.window.clear(); var canvas = createCairoCanvas(); var x0 = 25.6; var y0 = 25.6; var rect_width = 204.8; var rect_height = 204.8; var radius = 102.4; var x1, y1; x1 = x0 + rect_width; y1 = y0 + rect_height; if( rect_width/2 < radius ) { if( rect_height/2<radius ) { canvas.moveTo( x0, (y0+y1)/2 ); canvas.bezierCurveTo( x0, y0, x0, y0, (x0+x1)/2, y0 ); canvas.bezierCurveTo( x1, y0, x1, y0, x1, (y0+y1)/2 ); canvas.bezierCurveTo( x1, y1, x1, y1, (x0+x1)/2, y1 ); canvas.bezierCurveTo( x0, y1, x0, y1, x0, (y0+y1)/2 ); } else { canvas.moveTo( x0, y0+raius ); canvas.bezierCurveTo( x0, y0, x0, y0, (x0+x1)/2, y0 ); canvas.bezierCurveTo( x1, y0, x1, y0, x1, y0+radius ); canvas.lineTo( x1, y1-radius ); canvas.bezierCurveTo( x1, y1, x1, y1, (x1+x0)/2, y1 ); canvas.bezierCurveTo( x0, y1, x0, y1, x0, y1-radius ); } } else { if( rect_height/2<radius ) { canvas.moveTo( x0, (y0+y1)/2 ); canvas.bezierCurveTo( x0, y0, x0, y0, x0+radius, y0 ); canvas.lineTo( x1-radius, y0 ); canvas.bezierCurveTo( x1, y0, x1, y0, x1, (y0+y1)/2 ); canvas.bezierCurveTo( x1, y1, x1, y1, x1-radius, y1 ); canvas.lineTo( x0+radius, y1 ); canvas.bezierCurveTo( x0, y1, x0, y1, x0, (y0+y1)/2 ); } else { canvas.moveTo( x0, y0+radius ); canvas.bezierCurveTo( x0, y0, x0, y0, x0+radius, y0 ); canvas.lineTo( x1-radius, y0 ); canvas.bezierCurveTo( x1, y0, x1, y0, x1, y0+radius ); canvas.lineTo( x1, y1-radius ); canvas.bezierCurveTo( x1, y1, x1, y1, x1-radius, y1 ); canvas.lineTo( x0+radius, y1 ); canvas.bezierCurveTo( x0, y1, x0, y1, x0, y1-radius ); } } canvas.closePath(); canvas.fillStyle = "rgb( 128, 128, 255 )"; canvas.fill(); // no fill_preserve(), so you won't see the border. canvas.strokeStyle = "rgb( 255, 0, 0 )"; canvas.globalAlpha = 0.5; canvas.lineWidth = 10; canvas.stroke(); return true; } function curveToDemo() { drawingArea.window.clear(); var canvas = createCairoCanvas(); var x=25.6, y=128; var x1=102.4, y1=230.4, x2=153.6, y2=25.6, x3=230.4, y3=128.0; canvas.moveTo( x, y ); canvas.bezierCurveTo( x1, y1, x2, y2, x3, y3 ); canvas.lineWidth = 10; canvas.stroke(); canvas.strokeStyle = "rgb( 255, 51, 51 )"; canvas.globalAlpha = 0.6; canvas.lineWidth = 6; canvas.moveTo( x, y ); canvas.lineTo( x1, y1 ); canvas.moveTo( x2, y2 ); canvas.lineTo( x3, y3 ); canvas.stroke(); return true; } function rotateDemo() { drawingArea.window.clear(); var canvas = createCairoCanvas(); canvas.translate( 128, 128 ); canvas.rotate( 45*Math.PI/180 ); canvas.scale( 0.9, 0.9 ); canvas.fillStyle = "rgb(200,0,0)"; canvas.fillRect( 10, 10, 55, 50 ); canvas.strokeStyle = "rgb( 0, 200, 0 )"; canvas.strokeRect( 50, 50, 155, 150 ); canvas.strokeStyle = "rgb( 0, 0, 255 )"; canvas.arc( 137.5, 137.5, 100, 0, Math.PI*2, true ); canvas.stroke(); return true; } // // routines // function createButton( label, handler ) { var button = new Gtk.Button( {label: label} ); button.signal.clicked.connect( handler ); return button; } function createButtonGroup() { var buttonGroup = new Gtk.VBox(); //var buttonGroup = new Gtk.VButtonBox(); buttonGroup.pack_start( createButton( "Stroke", function() { exposeEvent = strokeDemo; return exposeEvent(); }), true, true); buttonGroup.pack_start( createButton( "Fill", function() { exposeEvent = fillDemo; return exposeEvent(); }), true, true); buttonGroup.pack_start( createButton( "4 color", function() { exposeEvent = fourColorDemo; return exposeEvent(); }), true, true); buttonGroup.pack_start( createButton( "Path", function() { exposeEvent = pathDemo; return exposeEvent(); }), true, true); buttonGroup.pack_start( createButton( "Scale and Transform", function() { exposeEvent = scaleAndTransformDemo; return exposeEvent(); }), true, true); buttonGroup.pack_start( createButton( "Arc", function() { exposeEvent = arcDemo; return exposeEvent(); }), true, true); buttonGroup.pack_start( createButton( "Clip", function() { exposeEvent = clipDemo; return exposeEvent(); }), true, true); buttonGroup.pack_start( createButton( "Curve Rectangle", function() { exposeEvent = curveRectangleDemo; return exposeEvent(); }), true, true); buttonGroup.pack_start( createButton( "Curve To", function() { exposeEvent = curveToDemo; return exposeEvent(); }), true, true); buttonGroup.pack_start( createButton( "Rotate", function() { exposeEvent = rotateDemo; return exposeEvent(); } ), true, true); return buttonGroup; } // // Events // function drawingArea_ExposeEvent() { return exposeEvent(); } // // Main // // Make the program terminate when the window is closed window.signal.hide.connect(Gtk.main_quit); drawingArea.signal.expose_event.connect( drawingArea_ExposeEvent ); hbox.pack_start( createButtonGroup(), false, false); hbox.pack_start( drawingArea, true, true ); vbox.pack_start( hbox, true, true ); vbox.pack_start( status, false, false, 0); window.add(vbox); window.show_all(); window.resize( 640, 480 ); // Start the main GTK+ loop and initiate the program Gtk.main();
關於這個例子,大部分都是從 Cairo網站上的範例搬來的,也幾乎演示了所有的函數,但還是有少數函數與屬性沒有涵蓋到,如 transform、setTransform、clearRect、quadraticCurveTo…等~
有需要再自己去翻 seed-canvas.c 看吧~
export GTK_IM_MODULE=gcin export QT_IM_MODULE=gcin
,這裡的 gcin,你可以替換為自己熟悉的輸入法,例如 scim、fcitx…。
在Ubuntu裡安裝 Seed 很簡單,參考PPA for Orange Owners裡,把
deb http://ppa.launchpad.net/orange-owners/ppa/ubuntu intrepid main deb-src http://ppa.launchpad.net/orange-owners/ppa/ubuntu intrepid main
放到 /etc/sources.list 裡,然後用 sudo apt-get update 更新,sudo apt-get install seed 來安裝即可。
執行 script 也很簡單,有兩種方法:
目前官方沒有文件說明 Seed 內部有哪些類別與方法,這很讓人困擾,這兩天看了 source code 跟 example code 之後,大致上有點了解。
Seed 主要的類別是 Seed,提供了如下方法:
Seed.include("other.js");
Seed.print("Hello world!");
try { Seed.check_syntax("Seed.print(;"); Seed.print("syntax ok!"); } catch( e ) { Seed.print( e.message ); }
var result = Seed.spawn("ls"); Seed.print( "=== spawn result(stdout) ===" ); Seed.print( result.stdout ); Seed.print( "=== spawn result(stderr) ===" ); Seed.print( result.stderr );
var pid = Seed.fork(); if( pid == 0 ) { // child process var result = Seed.spawn( "ls" ); Seed.print( result.stdout ); Seed.quit(); } else if( pid == -1 ) { Seed.print( "cannot create child process." ); } else { // parent process. Seed.print( "I am parent process." ); }
在 bash 下很簡單的一件事情,批次檔似乎沒有比較好的解~
在 bash 下:
VERSION=`cat version.txt`
在批次檔裡,我發現可以用 for 來解:
@For /f "" %%a in (version.txt) do (set VERSION=%%a)
但缺點是,當檔案有多行時,VERSION 會是最後一行的內容。
利用 jqGrid 新增中文欄位資料時,到伺服器端時,就變成亂碼了。
請 FireBug 大神幫忙,發現 request header content-type 的編碼是 utf-8,查過jqGrid的 source code,裡面也只是調用 jQuery 的 ajax 函數而已。
照理來說,應該可以用 $.ajaxSetup() 來修正,但試了好一陣子,發現沒辦法,即使我在 contentType 裡指定了 charset=big5,最後送出時,仍然會是 utf-8…
好吧,山不轉路轉,再拜請Google大神,發現有人利用 escape() 解,也就是先用 javascript escape() 編碼,server 端再解碼,這樣就解了。
大致的代碼是這樣:
// $("#jqGrid2").jqGrid( // ... 略 ... ).navGrid( "#pager2", { // ... 略 ... add:true, addfunc: function() { $("#jqGrid2").editGridRow( "new", { url: "server.asp", beforeSubmit: function( postdata, o ) { var s = postdata[ "your_field_name" ]; var ret=[true, "", ""]; postdata[ "your_field_name" ] = escape( s ); return ret; } } ); return false; } } );
偷懶,看看上面的日期,居然也快滿一個月了。跟去年同期比起來,少看很多~
Xming 等同是 Windows 上的 X Server,使用的說明可以參考:Xming 簡易使用說明,圖文並茂,寫的非常好。
對我來說,唯一的問題是字太小,該怎麼解決?我找了好久~
最後終於意外發現,只要在 XLaunch 最後一個步驟的畫面的 “Additional parameters for Xming” 裡填上 -dpi 100,就可以解決字太小的問題。
一月底的時候,Foxit釋出了Foxit Reader 1.0 Beta for Desktop Linux,很可惜的是,官方沒有提供 .deb 的版本。
不過沒關係,我們有外星人(alien)。