13 Aralık 2017 Çarşamba

Yaz Stajı ve Libreoffice Calc Üzerinde Hata Çözümü


Merhabalar, bu yazımda yaz stajımda neler yaptığımı, neler öğrendiğimi yazacağım. Üstteki resim genel olarak ne yaptığımı özetliyor aslında. Stajımlarımın ikisinide Kripton N-G şirketinde şirketinde Gülşah KÖSE'nin yanında yaptım. Kripton N-G şirketi Özgür yazılım çözümleri ve göç hizmetleri yapmakta ve bünyesindeki geliştiricilerin tamamı Libreoffice geliştiricisi olan Türkiyedeki tek şirket.

Daha önceden Libreoffice ile çalışmadığım için ilk önce derleme yapmayı öğrendim. İlk derleme işlemi uzun sürsede, ilk derleme sonrasında değişiklikler yapıldığında kısa bir sürede derleme işlemi tamamlanmakta. Staj süresince Libreoffice OOXML filtrelerinde çalıştım ve bununla ilgili bir hatayı çözdüm.

 https://bugs.documentfoundation.org/show_bug.cgi?id=83672 linkinden çözdüğüm hatanın kayıdını görebilirsiniz.

OOXML'den kısaca bahsetmek gerekirse kendisi xml tabanlı olup elektronik ofis dosyalarını saklamak için kullanılan bir dosya sistemidir. Microsoft Office programında(2007 sürümü ve sonrası) oluşturulan tüm dökümanlar bu dosya sistemiyle kaydedilirler. Aslında bir ofis belgesi arşivlenmiş xml dosyalarından ibarettir. Belgeye eklenen resim ve video gibi öğeler bu arşivin içerisinede eklenirler. OOXML filtreleri Libreoffice göçü için önemli bir engel ve geliştiricisi diğer kısımlara göre daha az olan bir alan.


Libreoffice, Microsoft Office dosyalarını açarken izlenen yol tam olarak böyle


Hatanın çözümü için ilk önce iki adet test dökümanı oluşturdum. Oluşturduğum dökümanlardaki farka bakarak döndürme parametresinin hangi etikette verildiğini öğrendim. <xfrm> etiketinde rot parametresi ile verilen değerin resimin döndürme açısı olduğunu öğrendim. writerfilter/source/ooxml/model.xml dosyasını inceleyerek bu değerin hangi komplex tipe atandığını öğrendim ve kaynak kod üzerinde arama yaparak oox/source/drawingml/transform2dcontext.cxx dosyasında olduğunu öğrendim. Bu dosyayı biraz incelediğimde ise hatanın olmadığına kanaat getirdim.

Libreoffice Bugzilla sayfasında üzerinde çalıştığım hata kaydının yorumlarına baktığımda Excelde oluşturulan metin kutuları 90 derece döndürülmüş çıktığı için çapaları anchortwocell olan tüm şekillerin döndürülmesi 0 a eşitlenmiş olduğunu gördüm. Bu hatanın asıl sebebini birkaç gün önce ikinci hatamı çözdüğümde anladım. Microsoft ofiste dikey olarak oluşturulan ve 90 derece döndürülen bir metin kutusu xml olarak kaydedilirken metin kutusunun son halinin koordinatları kayıt ediliyor ve bir döndürme açısı xml dosyasına yazılıyordu. Libreoffice ise bunu içe aktarırken koordinatlara göre metin kutusunu oluşturuyor ve döndürme açısına göre tekrar döndürüyordu. Bunu durdurmak için anchortwocell olan tüm şekillerin döndürme açısını 0 yapmışlardı fakat resimlerde şekil olarak işlendiği için yapılan değişiklik resimlerin dönmesini engelliyordu.

Bir metin kutusu içeren ve bir resim içeren iki xlsx dosyası oluşturdum ve aralarındaki farka baktım. Tüm etiketlere bakarak farklılıkları ve bu etiketlerin tanımlandığı yeri bulmaya çalışsamda çözüm en basit olan yöntemdi. Resimlerin çapaları anchortwocell olmasına rağmen editAs="oneCell" parametresine sahiplerdi. editAs="oneCell" parametresinin sc/source/filter/oox/drawingbase.cxx üzerinde olduğunu gördüm. Değişiklik yapmam gereken dosya sc/source/filter/oox/drawingfragment.cxx olduğu için nasıl erişeceğimi bilemedim ve bununla uzun bir süre uğraştım. drawingfragment.cxx dosyasını incelerken mxAnchor->getEditAs() diye bir fonksiyon olduğunu keşfettim ve buna göre bir kontrol ifadesi yazdım. Şeklimiz anchortwocell ise ve editAs="oneCell" parametresine sahip değil ise döndürme açısı 0 olacaktı. Böylelikle metin kutularının döndürme açısı 0 olacak resimler ise xml dosyasındaki açıya göre işlem görecek.

Hatayı çözüp unit testler ile bir derleme yaptıktan sonra diğer özelliklere zarar vermediğini anladım ve Libreoffice gerrit sistemine yolladım. Filtreler ile yapılan değişiklikler unit test olmadan alınmayacağı için unit test yazmam istendi. Unit test bir özelliğin yapılan değişiklikler sonucunda değişmediğini öğrenmek için gerekli ve filtreler için hayati önem taşımaktadır. Unit test için bir test dökümanı oluşturdum ve içine sadece döndürülmüş bir resim ekledim. Sonrasında bana örnek olması için atılan unit testi inceleyerek bu dosyaya ve içerisindeki şekil sınıfına eriştim. Bu şekilin özelliklerinden döndürme açısını aldım ve 0'a eşitse hata vermesi için gereken kontrol satırını yazıp gönderdim. Gönderme işlemi sırasında üzerinde çalıştığım satırlarda başka birisininde değişiklik yaptığını ve rebase etmem gerektiğini öğrendim. Bu işlemler içinde uğraştıktan sonra yamamı gönderdim ve kısa bir sürede kabul edildi. Artık xlsx dosyalarındaki döndürülmüş resimler düz çıkmıyor ... \o/
 


Libreoffice kaynak kodu üzerinde yaptığım değişiklikler ve yazdığım unit test:
https://gerrit.libreoffice.org/#/c/40790/